diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index fc387dfa3..000000000 --- a/.gitmodules +++ /dev/null @@ -1,36 +0,0 @@ -[submodule "test/token/beaba"] - path = test/token/beaba - url = https://github.com/ichiriac/beaba.git -[submodule "test/token/laravel"] - path = test/token/laravel - url = https://github.com/laravel/laravel.git -[submodule "test/token/zf2"] - path = test/token/zf2 - url = https://github.com/zendframework/zf2.git -[submodule "test/token/symfony"] - path = test/token/symfony - url = https://github.com/symfony/symfony.git -[submodule "test/token/tcpdf"] - path = test/token/tcpdf - url = https://github.com/tecnickcom/TCPDF -[submodule "test/token/evernote-cloud-sdk-php"] - path = test/token/evernote-cloud-sdk-php - url = https://github.com/evernote/evernote-cloud-sdk-php.git -[submodule "test/token/yii2"] - path = test/token/yii2 - url = https://github.com/yiisoft/yii2.git -[submodule "test/token/CodeIgniter"] - path = test/token/CodeIgniter - url = https://github.com/bcit-ci/CodeIgniter.git -[submodule "test/token/magento1"] - path = test/token/magento1 - url = https://github.com/bragento/magento-core -[submodule "test/token/magento2"] - path = test/token/magento2 - url = https://github.com/magento/magento2 -[submodule "test/token/opencart"] - path = test/token/opencart - url = https://github.com/opencart/opencart.git -[submodule "test/php-langspec"] - path = test/php-langspec - url = https://github.com/glayzzle/php-langspec.git diff --git a/.npmignore b/.npmignore index 94faa1731..3aa217c92 100644 --- a/.npmignore +++ b/.npmignore @@ -1,2 +1,3 @@ -/bin/ -/test/ \ No newline at end of file +/docs/ +/test/ +/gruntfile.js diff --git a/.travis.yml b/.travis.yml index d88da2bc8..cc37c5494 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,10 @@ language: node_js node_js: - '0.12' +cache: + bundler: true + directories: + - node_modules # NPM package notifications: email: false webhooks: @@ -9,11 +13,5 @@ notifications: on_success: change on_failure: always on_start: never -before_script: - - sudo apt-get install python-software-properties -y - - sudo LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php -y - - sudo apt-get update -y - - sudo apt-get install php7.0 php7.0-xml -y - - php -v script: npm run cover after_success: cat /home/travis/build/glayzzle/php-parser/coverage/lcov.info | /home/travis/build/glayzzle/php-parser/node_modules/coveralls/bin/coveralls.js diff --git a/README.md b/README.md index 824a0e9f3..716fb02d9 100644 --- a/README.md +++ b/README.md @@ -15,22 +15,24 @@ Parse PHP code from NodeJS and convert it to AST. This library is a standalone m $ npm install php-parser --save ``` -# Try it - -```sh -$ cd bin -$ node test.js -e "echo 'Hello World';" -``` +# Use it -Will output : ```js -*** START TESTING *** +// initialize a new parser instance +var parser = require('php-parser').create(); --- TOKENS : -T_ECHO T_CONSTANT_ENCAPSED_STRING ; +// how to retrieve the AST +var AST = parser.parseEval('echo "Hello World";'); --- AST : +// how to list tokens +var tokens = parser.tokenGetAll(' - - -f Parse and test the specified file - -d Parse each file in the specified path - -r Use recursivity with the specified path - -e Eval the specified input and shows AST - -v Enable verbose mode and show debug - -h, --help Print help and exit -``` +# Contributing -If you run into problems with a test, run it with the cli and add the `--debug` flag. +If you want to contribute please visit this repository https://github.com/glayzzle/php-parser-dev. # Misc diff --git a/RELEASE.md b/RELEASE.md index d5640771b..e64f17b07 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,5 +1,14 @@ # Releases +## 1.0.0 : (2016-12-29) + +- All nodes are now converted to objects +- Bruteforce tests are in a separate project +- Improved tests with mocha +- Many syntax fixes +- Tests over a silent error mode +- Release of a complete AST documentation + ## 0.1.5 : (2016-12-27) > The 0.1.x version starts to be deprecated diff --git a/bin/bench.js b/bin/bench.js deleted file mode 100644 index 039d04ee1..000000000 --- a/bin/bench.js +++ /dev/null @@ -1,218 +0,0 @@ -/** - -Bench to chose between Nested Arrays or Object for AST : - -Array Write 4.6 ms -Object Write 5.6 ms - -Array Memory 210 kb -Object Memory 696 kb - -Array Read 1.8 ms -Object Read 11.8 ms - -**/ - -var fs = require('fs'); -var memwatch = require('memwatch-next'); - - -console.log('\n--- array vs object for storing AST :'); - -function duration(text, hrTime) { - var diff = process.hrtime(hrTime); - diff = diff[0] * 1000000 + diff[1] / 1000; - // console.log(text, Math.round(diff / 1000) + 'ms'); - return Math.round(diff / 1000); -} - -function runWrite(size) { - if (typeof global.gc === 'function') global.gc(); - var result = []; - var hrTime = false; - var test1 = []; - var hd = false, diff = false; - // test 1 - hd = new memwatch.HeapDiff(); - hrTime = process.hrtime(); - for(var i = 0; i < size; i++) { - test1.push(['class', 'foo', []]); - } - result.push( - duration('Array init time', hrTime) - ); - - diff = hd.end(); - result.push(diff.after.size_bytes - diff.before.size_bytes); - - // test 2 - test1 = []; - hd = new memwatch.HeapDiff(); - hrTime = process.hrtime(); - for(var i = 0; i < size; i++) { - test1.push({type: 'class', name: 'foo', meta: []}); - } - result.push( - duration('Object init time', hrTime) - ); - diff = hd.end(); - result.push(diff.after.size_bytes - diff.before.size_bytes); - return result; -} - - -function runRead(size) { - var result = []; - var arr = [ - ['class', 'foo', []] - ]; - var obj = [ - {type: 'class', name: 'foo', meta: []} - ]; - var ok = false; - var hrTime = process.hrtime(); - for(var i = 0; i < size; i++) { - ok = arr[0][0] === 'class' && arr[0][1] === 'foo'; - } - result.push( - duration('Array read time', hrTime) - ); - hrTime = process.hrtime(); - for(var i = 0; i < size; i++) { - ok = obj[0].type === 'class' && arr[0].name === 'foo'; - } - result.push( - duration('Object read time', hrTime) - ); - return result; -} - -var time = [0, 0]; -var memory = [0, 0]; -var size = 10; -for(var i = 0; i < size; i++) { - var result = runWrite(2000); - time[0] += result[0]; - time[1] += result[2]; - memory[0] += result[1]; - memory[1] += result[3]; -} - -console.log('Array Write', time[0] / size, 'ms'); -console.log('Object Write', time[1] / size, 'ms'); - -console.log('Array Memory', memory[0] / size / 1024, 'kb'); -console.log('Object Memory', memory[1] / size / 1024, 'kb'); - -time = [0, 0]; -for(var i = 0; i < size; i++) { - var result = runRead(100000); - time[0] += result[0]; - time[1] += result[1]; -} - -console.log('Array Read', time[0] / size, 'ms'); -console.log('Object Read', time[1] / size, 'ms'); - - - -// preparing files for tests -var files = []; -var path = __dirname + '/../test/token/'; -var items = fs.readdirSync(path); -for(var i = 0; i < items.length; i ++) { - var file = items[i]; - if (file[0] != '.') { - var stat = fs.statSync(path + file); - if (!stat.isDirectory()) { - files.push( - fs.readFileSync(path + file, { - encoding: 'binary' - }) - ); - } - } -} - -// test FN -function consumeTokens(engine, files) { - if (typeof global.gc === 'function') global.gc(); - var tSize = 0; - var hd = new memwatch.HeapDiff(); - var hrstart = process.hrtime(); - for(var n = 0; n < 1000; n++) { // repeat tests to increase accuracy - for(var i = 0; i < files.length; i++) { - engine.lexer.setInput(files[i]); - var EOF = engine.lexer.EOF; - var token = engine.lexer.lex() || EOF; - while(token != EOF) { - token = engine.lexer.lex() || EOF; - tSize++; - } - } - } - var hrend = process.hrtime(hrstart); - diff = hd.end(); - var duration = (hrend[0] * 1000000 * 1000) + hrend[1]; - console.log('Tokens extracted :', tSize); - console.log('Tokens by sec (x1000) :', (Math.round((tSize / (duration / 1000000 / 1000)) / 100) / 10)); - console.log('Total duration :', Math.round(duration / 100000) / 10, 'ms'); - console.log('Memory : ', Math.round((diff.after.size_bytes - diff.before.size_bytes) / 1024), 'kb'); - return { - duration: duration, - memory: diff.after.size_bytes - diff.before.size_bytes - }; -} - -function compareResults(a, b) { - if (a.duration < b.duration) { - console.log('Is ' + Math.round(((b.duration / a.duration) - 1) * 100) + '% more rapid'); - } else { - console.log('Is ' + Math.round(((a.duration / b.duration) - 1) * 100) + '% more slower'); - } - if (a.memory < b.memory) { - console.log('Use ' + Math.round((1 - (a.memory / b.memory)) * 100) + '% less memory '); - } else { - console.log('Use ' + Math.round((1 - (b.memory / a.memory)) * 100) + '% more memory '); - } -} - -// parsing tests -if (typeof global.gc === 'function') global.gc(); -console.log('\n--- parsing files - actual lexer version :'); -var engine = require('../src/index'); -engine.lexer.asp_tags = true; -engine.lexer.short_tags = true; -var actual = consumeTokens(engine, files); - -// test the old library version -if (typeof global.gc === 'function') global.gc(); -console.log('\n--- parsing files - jison lexer version :'); -engine.lexer = require('./jison-lexer'); -engine.lexer.asp_tags = true; -engine.lexer.short_tags = true; -var jison = consumeTokens(engine, files); - -// original php results -console.log('\n--- parsing files - plain PHP version :'); -var cmd = require('./formats/cmd'); -var result = cmd.exec('php -d short_open_tag=1 ' + __dirname + '/bench.php -d ' + path); -var php = false; -try { - php = JSON.parse(result.stdout); - console.log('Tokens extracted :', php.count); - console.log('Tokens by sec (x1000) :', (Math.round((php.count / (php.duration / 1000000 / 1000)) / 100) / 10)); - console.log('Total duration :', Math.round(php.duration / 100000) / 10, 'ms'); - console.log('Memory : ', Math.round(php.memory / 1024), 'kb'); -} catch(e) { - console.log('Fail to parse output : ', result.stdout); -} - - -// results -console.log('\n--- results Actual vs Jison :'); -compareResults(actual, jison); -console.log('\n--- results Actual vs PHP :'); -compareResults(actual, php); -console.log('\n--- results Jison vs PHP :'); -compareResults(jison, php); diff --git a/bin/bench.php b/bin/bench.php deleted file mode 100644 index 5bcf8487c..000000000 --- a/bin/bench.php +++ /dev/null @@ -1,35 +0,0 @@ - $count, - 'memory' => $mem, - 'duration' => $duration - )); \ No newline at end of file diff --git a/bin/formats/ast.js b/bin/formats/ast.js deleted file mode 100644 index 8fcc7431e..000000000 --- a/bin/formats/ast.js +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Copyright (C) 2014 Glayzzle (BSD3 License) - * @authors https://github.com/glayzzle/php-parser/graphs/contributors - * @url http://glayzzle.com - */ -var fs = require('fs'); -var util = require('util'); - -module.exports = { - handles: function(filename, ext) { - return filename.indexOf("/ast/") > -1 && ( - ext == '.php' - || ext == '.phtml' - || ext == '.html' - ); - } - ,run: function(filename, php) { - var parser = php.parser(); - parser.lexer.all_tokens = false; - parser.lexer.mode_eval = false; - try { - var AST = parser.parseCode( - fs.readFileSync(filename).toString() - ); - console.log( - util.inspect( - AST, { - showHidden: false, - depth: 10, - colors: true - } - ) - ); - return true; - } catch(e) { - console.error(e); - return false; - } - } -}; \ No newline at end of file diff --git a/bin/formats/ast.php b/bin/formats/ast.php deleted file mode 100644 index 0176e54f6..000000000 --- a/bin/formats/ast.php +++ /dev/null @@ -1,44 +0,0 @@ - ast\get_kind_name($node->kind), - 'lineno' => $node->lineno - ); - if ($node->flags > 0) { - $result['flags'] = ast\kind_uses_flags($node->flags); - } - if ($node instanceof ast\Node\Decl) { - $result['endLineno'] = $node->endLineno; - $result['name'] = $node->name; - $result['docComment'] = getNode($node->docComment); - } - if ($node->children) { - $result['children'] = getNode($node->children); - } - return $result; - } - - echo json_encode( getNode($ast) ); diff --git a/bin/formats/cmd.js b/bin/formats/cmd.js deleted file mode 100644 index e8dfb1639..000000000 --- a/bin/formats/cmd.js +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (C) 2014 Glayzzle (BSD3 License) - * @authors https://github.com/glayzzle/php-parser/graphs/contributors - * @url http://glayzzle.com - */ -var child_process = require('child_process'); -var fs = require('fs'); - -module.exports = { - exec: function(command) { - var out = ""; - try { - out = child_process.execSync(command).toString(); - } catch(e) { - if (e.stdout) { - out += e.stdout.toString(); - } - if (e.stderr) { - out += e.stderr.toString(); - } - } - // Output - return { stdout: out }; - }, - checkError: function(file) { - var cmd = 'php -l ' + file; - var error = false; - try { - error = child_process.execSync(cmd).toString(); - } catch(e) { - error = e.stdout.toString() + e.stderr.toString(); - } - if (!error) return false; - error = error.match(/syntax error.*on line ([0-9]+)/i); - if (error && error.length === 2) { - return parseInt(error[1]); - } else { - return false; - } - } -}; \ No newline at end of file diff --git a/bin/formats/parser.js b/bin/formats/parser.js deleted file mode 100644 index 7450e7893..000000000 --- a/bin/formats/parser.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Copyright (C) 2014 Glayzzle (BSD3 License) - * @authors https://github.com/glayzzle/php-parser/graphs/contributors - * @url http://glayzzle.com - */ -var util = require('util'); - -module.exports = { - explode: true - ,handles: function(filename, ext) { - return ext == '.parser'; - } - // runs a parser file : test parsing behaviours - ,run: function(data, filename, engine) { - try { - if (engine.parser.debug) { - console.log(' >> Start test : ' + data.shift()); - } - var test = { - buffer: '', - mode: '' - }; - var tests = []; - data.forEach(function(line) { - if (line.substring(0, 2) == '--') { - if (test.mode != '') tests.push(test); - test = { - buffer: '', mode: line.substring(2, line.length - 2) - }; - } else { - test.buffer += line + '\r\n'; - } - }); - if (test) tests.push(test); - var writer; - var ok; - for(var i = 0; i < tests.length; i++) { - test=tests[i]; - engine.parser.debug && console.log(' mode : ' + test.mode); - if (test.mode.substring(0, 4) == 'FAIL') { - ok = false; - try { - var ast = engine.parseEval(test.buffer); - ok = true; - if (engine.parser.debug) { - console.log( - util.inspect( - ast, { - showHidden: false, - depth: 10, - colors: true - } - ) - ); - } - } catch(e) { - engine.parser.debug && console.log(e); - ok = false; - } - if (ok) { - throw new Error('Test should fail to parse : \n>> ' + test.buffer); - } - } else { - try { - var ast = engine.parseEval(test.buffer); - if (engine.parser.debug) { - console.log( - util.inspect( - ast, { - showHidden: false, - depth: 10, - colors: true - } - ) - ); - } - } catch(e) { - e.source = test.buffer; - throw e; - } - } - } - return true; - } catch(e) { - // @fixme - this function does not exists, should be declared in parser.js ? - throw e; - // engine.parseError(e, e.source); - return false; - } - } -}; diff --git a/bin/formats/php.js b/bin/formats/php.js deleted file mode 100644 index e6ca98ffa..000000000 --- a/bin/formats/php.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright (C) 2014 Glayzzle (BSD3 License) - * @authors https://github.com/glayzzle/php-parser/graphs/contributors - * @url http://glayzzle.com - */ - -var fs = require('fs'); -var util = require('util'); -var cmd = require('./cmd'); - -module.exports = { - handles: function(filename, ext) { - return ext == '.php' || ext === '.phtml'; - } - // runs the specified filename - ,run: function(filename, engine) { - return true; - var ast = false; - try { - ast = engine.parseCode( - fs.readFileSync(filename).toString() - ); - } catch(e) { - var hasError = cmd.checkError(filename); - var line = engine.lexer.yylloc.first_line; - if (hasError === false) { - throw e; - } else if (hasError != line) { - console.error('Found error at', line, 'but expected at', hasError); - throw e; - } else { - if (engine.parser.debug) { - console.log('! - Found error at', line, 'but it\'s ok'); - } - return true; - } - } - if (engine.parser.debug) { - console.log( - util.inspect( - ast, { - showHidden: false, - depth: 10, - colors: true - } - ) - ); - } - if (ast[0] === 'program') { - engine.parser.debug && console.log('v - Passed AST parsing'); - return true; - } else { - console.error('x - Warning : the AST tree is empty'); - return false; - } - } -}; \ No newline at end of file diff --git a/bin/formats/phpt.js b/bin/formats/phpt.js deleted file mode 100644 index 73a82ed0a..000000000 --- a/bin/formats/phpt.js +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Copyright (C) 2014 Glayzzle (BSD3 License) - * @authors https://github.com/glayzzle/php-parser/graphs/contributors - * @url http://glayzzle.com - */ -var util = require('util'); - -module.exports = { - explode: true - ,handles: function(filename, ext) { - return ext == '.phpt'; - } - // runs a parser file : test parsing behaviours - ,run: function(data, filename, engine) { - try { - var test = { - buffer: '', - mode: '' - }; - var tests = []; - data.forEach(function(line) { - if (line.substring(0, 2) == '--') { - if (test.mode != '') tests.push(test); - test = { - buffer: '', mode: line.substring(2, line.length - 2) - }; - } else { - test.buffer += line + '\r\n'; - } - }); - if (test) tests.push(test); - - var ok = true; - for(var i = 0; i < tests.length; i++) { - test=tests[i]; - if (test.mode === 'TEST') { - engine.parser.debug && console.log('> ' + test.buffer.trim()); - continue; - } - var mode = test.mode.split(':'); - if (mode[0] === 'FILE') { - try { - var ast = engine.parseCode(test.buffer); - if (engine.parser.debug) { - console.log( - util.inspect( - ast, { - showHidden: false, - depth: 10, - colors: true - } - ) - ); - } - if (mode.length > 1 && mode[1] === 'FAIL') { - ok = false; - console.log('Should fail at line ' + mode[2]); - } - } catch(e) { - if (mode.length > 1 && mode[1] === 'FAIL') { - if (engine.parser.lastError.line != mode[2]) { - ok = false; - console.log( - 'Expected to fail at line ' + mode[2] + - ' but fail at ' + engine.parser.lastError.line - ); - } - } else { - console.log(e.stack); - ok = false; - } - } - } else { - engine.parser.debug && console.log('IGNORE ' + test.mode); - } - } - return ok; - } catch(e) { - console.error(e.stack); - return false; - } - } -}; diff --git a/bin/formats/token.js b/bin/formats/token.js deleted file mode 100644 index bac4a2bf4..000000000 --- a/bin/formats/token.js +++ /dev/null @@ -1,163 +0,0 @@ -/** - * Copyright (C) 2014 Glayzzle (BSD3 License) - * @authors https://github.com/glayzzle/php-parser/graphs/contributors - * @url http://glayzzle.com - */ -var fs = require('fs'); -var cmd = require('./cmd'); -var util = require('util'); - -module.exports = { - handles: function(filename, ext) { - if (ext == '.out') { - fs.unlink(filename); - return false; - } - return filename.indexOf("/token/") > -1 && ( - ext == '.php' - || ext == '.phtml' - || ext == '.html' - ); - } - ,run: function(filename, engine) { - if (engine.parser.debug) console.log(filename); - // USING THE LEXER TO PARSE THE FILE : - var hrstart, mem, jsTok; - if (engine.parser.debug) { - hrstart = process.hrtime(); - mem = process.memoryUsage(); - } - var buffer = fs.readFileSync(filename, { - encoding: 'binary' - }); - jsTok = engine.tokenGetAll(buffer); - if (engine.parser.debug) { - var hrend = process.hrtime(hrstart); - if (hrend[1] > 0) - console.log( - 'Speed : ', - (Math.round(jsTok.length / 1000) / 10) + 'K Tokens parsed at ', - (Math.round(jsTok.length * 60000 / (hrend[1] / 1000000) / 1000 / 100) / 10) + 'M Token/sec - total time ', - Math.round(hrend[1] / 100000) / 10, 'ms' - ); - console.log('Memory : ', Math.round((process.memoryUsage().heapUsed - mem.heapUsed) / 1024), 'kb'); - } - - // USING THE PHP ENGINE TO PARSE - var result = cmd.exec('php -d short_open_tag=1 ' + (engine.lexer.asp_tags ? '-d asp_tags=1 ': '') + __dirname + '/token.php ' + filename); - var phpTok = false; - try { - phpTok = JSON.parse(result.stdout); - } catch(e) { - console.log('Fail to parse output : ', result.stdout); - if (engine.parser.debug) { - throw e; - } else { - return true; // ignore this test : php can't parse the file - } - } - - var fail = false; - var error = [[], []]; - - // CHECK ALL TOKENS - for(var i = 0; i < phpTok.length; i++) { - var p = phpTok[i]; - var j = jsTok[i]; - if (engine.parser.debug) { - if (j instanceof Array) { - console.log('JS('+j[2]+') : ', j[0], j[1]); - } - if (p instanceof Array) { - console.log('PHP('+p[2]+') : ', p[0], p[1]); - } - } - if ( p instanceof Array ) { - if ( j instanceof Array ) { - if (p[0] != j[0]) { // check the token type - if ( - (p[0] == 'T_LNUMBER' || p[0] == 'T_DNUMBER') - && (j[0] == 'T_LNUMBER' || j[0] == 'T_DNUMBER') - ) { - // @fixme : ignore numbers size - long are not handled in same way - } else { - console.log('FAIL : Expected ' + p[0] + ' token, but found ' + j[0]); - fail = true; - } - } - if (p[1] != j[1]) { // check the token contents - j[1] = JSON.parse( JSON.stringify( j[1] ) ); - console.log('FAIL : Expected "' + p[1] + '" contents, but found "' + j[1] + '"'); - fail = true; - } - if (p[2] != j[2]) { // check the token line - console.log('NOTICE : Expected line ' + p[2] + ', but found ' + j[2]); - fail = true; - } - } else { - console.log('FAIL : Expected ' + p[0] + ' token, but found "' + j + '" symbol'); - fail = true; - } - } else { - if ( j !== p ) { - console.log('FAIL : Expected "' + p + '", but found "' + j + '"'); - fail = true; - } - } - if (fail) { - error[0].push(j); - error[1].push(p); - break; - } - } - - // OUTPUT ERRORS IF FOUND - if (phpTok.length != jsTok.length) { - console.log('FAIL : Token arrays have not the same length !'); - fail = true; - } - if (fail) { - console.log('\nError at : ' + filename); - console.log('\nJS Tokens', error[0]); - console.log('PHP Tokens', error[1]); - // ADD A LOG FILE (FOR ANALYSIS) - fs.writeFileSync( - filename + '.out', - JSON.stringify(jsTok) - + "\n\n" + JSON.stringify(phpTok) - ); - return false; - } else { - // test the AST parser to ensure that the struture can be parsed - try { - var ast = engine.parseCode(buffer, { - parser: { - extractDoc: true - } - }); - if (ast[0] !== 'program') throw new Error('not a program node'); - if (engine.parser.debug) { - console.log( - util.inspect( - ast[1], { - showHidden: false, - depth: 10, - colors: true - } - ) - ); - } - } catch(e) { - console.log('v - Passed ' + jsTok.length + ' tokens (but AST warning)'); - console.log(filename); - console.log(e); - return true; - } - - if (engine.parser.debug) { - console.log('v - Passed ' + jsTok.length + ' tokens'); - } - return true; - } - } -}; \ No newline at end of file diff --git a/bin/formats/token.php b/bin/formats/token.php deleted file mode 100644 index 235008b33..000000000 --- a/bin/formats/token.php +++ /dev/null @@ -1,25 +0,0 @@ - $t) { - if (is_array($t)) { - $t[0] = token_name($t[0]); - $t[1] = utf8_encode($t[1]); - } - echo json_encode( $t ); - if ($p !== $last) { - echo ','; - } - } - echo ']'; diff --git a/bin/jison-lexer.js b/bin/jison-lexer.js deleted file mode 100644 index 3571e2bc1..000000000 --- a/bin/jison-lexer.js +++ /dev/null @@ -1,1646 +0,0 @@ - /** - * Copyright (C) 2014 Glayzzle (BSD3 License) - * @authors https://github.com/glayzzle/php-parser/graphs/contributors - * @url http://glayzzle.com - */ - -var T_HALT_COMPILER = 101, - T_USE = 102, - T_ENCAPSED_AND_WHITESPACE = 103, - T_OBJECT_OPERATOR = 104, - T_STRING = 105, - T_DOLLAR_OPEN_CURLY_BRACES = 106, - T_STRING_VARNAME = 107, - T_CURLY_OPEN = 108, - T_NUM_STRING = 109, - T_ISSET = 110, - T_EMPTY = 111, - T_INCLUDE = 112, - T_INCLUDE_ONCE = 113, - T_EVAL = 114, - T_REQUIRE = 115, - T_REQUIRE_ONCE = 116, - T_NAMESPACE = 117, - T_NS_SEPARATOR = 118, - T_AS = 119, - T_IF = 120, - T_ENDIF = 121, - T_WHILE = 122, - T_DO = 123, - T_FOR = 124, - T_SWITCH = 125, - T_BREAK = 126, - T_CONTINUE = 127, - T_RETURN = 128, - T_GLOBAL = 129, - T_STATIC = 130, - T_ECHO = 131, - T_INLINE_HTML = 132, - T_UNSET = 133, - T_FOREACH = 134, - T_DECLARE = 135, - T_TRY = 136, - T_THROW = 137, - T_GOTO = 138, - T_FINALLY = 139, - T_CATCH = 140, - T_ENDDECLARE = 141, - T_LIST = 142, - T_CLONE = 143, - T_PLUS_EQUAL = 144, - T_MINUS_EQUAL = 145, - T_MUL_EQUAL = 146, - T_DIV_EQUAL = 147, - T_CONCAT_EQUAL = 148, - T_MOD_EQUAL = 149, - T_AND_EQUAL = 150, - T_OR_EQUAL = 151, - T_XOR_EQUAL = 152, - T_SL_EQUAL = 153, - T_SR_EQUAL = 154, - T_INC = 155, - T_DEC = 156, - T_BOOLEAN_OR = 157, - T_BOOLEAN_AND = 158, - T_LOGICAL_OR = 159, - T_LOGICAL_AND = 160, - T_LOGICAL_XOR = 161, - T_SL = 162, - T_SR = 163, - T_IS_IDENTICAL = 164, - T_IS_NOT_IDENTICAL = 165, - T_IS_EQUAL = 166, - T_IS_NOT_EQUAL = 167, - T_IS_SMALLER_OR_EQUAL = 168, - T_IS_GREATER_OR_EQUAL = 169, - T_INSTANCEOF = 170, - T_INT_CAST = 171, - T_DOUBLE_CAST = 172, - T_STRING_CAST = 173, - T_ARRAY_CAST = 174, - T_OBJECT_CAST = 175, - T_BOOL_CAST = 176, - T_UNSET_CAST = 177, - T_EXIT = 178, - T_PRINT = 179, - T_YIELD = 180, - T_YIELD_FROM = 181, - T_FUNCTION = 182, - T_DOUBLE_ARROW = 183, - T_DOUBLE_COLON = 184, - T_ARRAY = 185, - T_CALLABLE = 186, - T_CLASS = 187, - T_ABSTRACT = 188, - T_TRAIT = 189, - T_FINAL = 190, - T_EXTENDS = 191, - T_INTERFACE = 192, - T_IMPLEMENTS = 193, - T_VAR = 194, - T_PUBLIC = 195, - T_PROTECTED = 196, - T_PRIVATE = 197, - T_CONST = 198, - T_NEW = 199, - T_INSTEADOF = 200, - T_ELSEIF = 201, - T_ELSE = 202, - T_ENDSWITCH = 203, - T_CASE = 204, - T_DEFAULT = 205, - T_ENDFOR = 206, - T_ENDFOREACH = 207, - T_ENDWHILE = 208, - T_CONSTANT_ENCAPSED_STRING = 209, - T_LNUMBER = 210, - T_DNUMBER = 211, - T_LINE = 212, - T_FILE = 213, - T_DIR = 214, - T_TRAIT_C = 215, - T_METHOD_C = 216, - T_FUNC_C = 217, - T_NS_C = 218, - T_START_HEREDOC = 219, - T_END_HEREDOC = 220, - T_CLASS_C = 221, - T_VARIABLE = 222, - T_OPEN_TAG = 223, - T_OPEN_TAG_WITH_ECHO = 224, - T_CLOSE_TAG = 225, - T_WHITESPACE = 226, - T_COMMENT = 227, - T_DOC_COMMENT = 228, - T_ELLIPSIS = 229, - T_COALESCE = 230, - T_POW = 231, - T_POW_EQUAL = 232; - -// DEFINE LONG SIZE -if (process.arch == 'x64') { - var SIZEOF_LONG = 8; - var MAX_LENGTH_OF_LONG = 20; - var long_min_digits = "9223372036854775808"; -} else { - var SIZEOF_LONG = 4; - var MAX_LENGTH_OF_LONG = 11; - var long_min_digits = "2147483648"; -} - -// check if is a -var IS_LABEL_START = function(c) { - return ( - c >= 'a' && c <= 'z' - ) || ( - c >= 'A' && c <= 'Z' - ) || ( - c == '_' || c >= 0x7F - ); -}; - -// escapes chars -var scan_escape_string = function(str) { - return str; -}; - -// consume the specified length on the lexer -var consume = function(lexer, size) { - if (size < 1) return false; - var ch, i; - // counting lines - for(i = 0; i < size; i++) { - ch = lexer._input[i]; - if (ch == '\n' || ch == '\r') { - lexer.yylineno++; - lexer.yylloc.last_line++; - lexer.yylloc.last_column = 0; - if (ch == '\r' && lexer._input[++i] == '\n') continue; // windows style - } else { - lexer.yylloc.last_column++; - } - } - // update offsets - if (lexer.options.ranges) lexer.yylloc.range[1] += size; - lexer.yyleng += size; - lexer.offset += size; - // update texts - ch = lexer._input.substring(0, size); - lexer.yytext += ch; - lexer.match += ch; - lexer.matched += ch; - lexer._input = lexer._input.slice(size); - return ch; -}; - -/* generated by jison-lex 0.3.4 */ -var lexer = (function(){ -var lexer = ({ - -EOF:1, - -parseError:function parseError(str, hash) { - if (this.yy.parser) { - this.yy.parser.parseError(str, hash); - } else { - throw new Error(str); - } - }, - -// resets the lexer, sets new input -setInput:function (input, yy) { - this.yy = yy || this.yy || {}; - this._input = input; - this._more = this._backtrack = this.done = false; - this.yylineno = this.yyleng = 0; - this.yytext = this.matched = this.match = ''; - this.conditionStack = ['INITIAL']; - this.yylloc = { - first_line: 1, - first_column: 0, - last_line: 1, - last_column: 0 - }; - if (this.options.ranges) { - this.yylloc.range = [0,0]; - } - this.offset = 0; - return this; - }, - -// consumes and returns one char from the input -input:function () { - var ch = this._input[0]; - this.yytext += ch; - this.yyleng++; - this.offset++; - this.match += ch; - this.matched += ch; - var lines = ch.match(/(?:\r\n?|\n).*/g); - if (lines) { - this.yylineno++; - this.yylloc.last_line++; - } else { - this.yylloc.last_column++; - } - if (this.options.ranges) { - this.yylloc.range[1]++; - } - - this._input = this._input.slice(1); - return ch; - }, - -// unshifts one char (or a string) into the input -unput:function (ch) { - var len = ch.length; - var lines = ch.split(/(?:\r\n?|\n)/g); - - this._input = ch + this._input; - this.yytext = this.yytext.substr(0, this.yytext.length - len); - //this.yyleng -= len; - this.offset -= len; - var oldLines = this.match.split(/(?:\r\n?|\n)/g); - this.match = this.match.substr(0, this.match.length - 1); - this.matched = this.matched.substr(0, this.matched.length - 1); - - if (lines.length - 1) { - this.yylineno -= lines.length - 1; - } - var r = this.yylloc.range; - - this.yylloc = { - first_line: this.yylloc.first_line, - last_line: this.yylineno + 1, - first_column: this.yylloc.first_column, - last_column: lines ? - (lines.length === oldLines.length ? this.yylloc.first_column : 0) - + oldLines[oldLines.length - lines.length].length - lines[0].length : - this.yylloc.first_column - len - }; - - if (this.options.ranges) { - this.yylloc.range = [r[0], r[0] + this.yyleng - len]; - } - this.yyleng = this.yytext.length; - return this; - }, - -// When called from action, caches matched text and appends it on next action -more:function () { - this._more = true; - return this; - }, - -// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. -reject:function () { - if (this.options.backtrack_lexer) { - this._backtrack = true; - } else { - return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), { - text: "", - token: null, - line: this.yylineno - }); - - } - return this; - }, - -// retain first n characters of the match -less:function (n) { - this.unput(this.match.slice(n)); - }, - -// displays already matched input, i.e. for error messages -pastInput:function () { - var past = this.matched.substr(0, this.matched.length - this.match.length); - return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, ""); - }, - -// displays upcoming input, i.e. for error messages -upcomingInput:function () { - var next = this.match; - if (next.length < 20) { - next += this._input.substr(0, 20-next.length); - } - return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, ""); - }, - -// displays the character position where the lexing error occurred, i.e. for error messages -showPosition:function () { - var pre = this.pastInput(); - var c = new Array(pre.length + 1).join("-"); - return pre + this.upcomingInput() + "\n" + c + "^"; - }, - -// test the lexed token: return FALSE when not a match, otherwise return token -test_match:function (match, indexed_rule) { - var token, - lines, - backup; - - if (this.options.backtrack_lexer) { - // save context - backup = { - yylineno: this.yylineno, - yylloc: { - first_line: this.yylloc.first_line, - last_line: this.last_line, - first_column: this.yylloc.first_column, - last_column: this.yylloc.last_column - }, - yytext: this.yytext, - match: this.match, - matches: this.matches, - matched: this.matched, - yyleng: this.yyleng, - offset: this.offset, - _more: this._more, - _input: this._input, - yy: this.yy, - conditionStack: this.conditionStack.slice(0), - done: this.done - }; - if (this.options.ranges) { - backup.yylloc.range = this.yylloc.range.slice(0); - } - } - - lines = match[0].match(/(?:\r\n?|\n).*/g); - if (lines) { - this.yylineno += lines.length; - } - this.yylloc = { - first_line: this.yylloc.last_line, - last_line: this.yylineno + 1, - first_column: this.yylloc.last_column, - last_column: lines ? - lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : - this.yylloc.last_column + match[0].length - }; - this.yytext += match[0]; - this.match += match[0]; - this.matches = match; - this.yyleng = this.yytext.length; - if (this.options.ranges) { - this.yylloc.range = [this.offset, this.offset += this.yyleng]; - } - this._more = false; - this._backtrack = false; - this._input = this._input.slice(match[0].length); - this.matched += match[0]; - token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); - if (this.done && this._input) { - this.done = false; - } - if (token) { - return token; - } else if (this._backtrack) { - // recover context - for (var k in backup) { - this[k] = backup[k]; - } - return false; // rule action called reject() implying the next rule should be tested instead. - } - return false; - }, - -// return next match in input -next:function () { - if (this.done) { - return this.EOF; - } - if (!this._input) { - this.done = true; - } - - var token, - match, - tempMatch, - index; - if (!this._more) { - this.yytext = ''; - this.match = ''; - } - var rules = this._currentRules(); - for (var i = 0; i < rules.length; i++) { - tempMatch = this._input.match(this.rules[rules[i]]); - if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { - match = tempMatch; - index = i; - if (this.options.backtrack_lexer) { - token = this.test_match(tempMatch, rules[i]); - if (token !== false) { - return token; - } else if (this._backtrack) { - match = false; - continue; // rule action called reject() implying a rule MISmatch. - } else { - // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) - return false; - } - } else if (!this.options.flex) { - break; - } - } - } - if (match) { - token = this.test_match(match, rules[index]); - if (token !== false) { - return token; - } - // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) - return false; - } - if (this._input === "") { - return this.EOF; - } else { - return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { - text: "", - token: null, - line: this.yylineno - }); - } - }, - -// return next match that has a token -lex:function lex() { - var r = this.next(); - if (r) { - return r; - } else { - return this.lex(); - } - }, - -// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) -begin:function begin(condition) { - this.conditionStack.push(condition); - }, - -// pop the previously active lexer condition state off the condition stack -popState:function popState() { - var n = this.conditionStack.length - 1; - if (n > 0) { - return this.conditionStack.pop(); - } else { - return this.conditionStack[0]; - } - }, - -// produce the lexer rule set which is active for the currently active lexer condition state -_currentRules:function _currentRules() { - if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { - return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; - } else { - return this.conditions["INITIAL"].rules; - } - }, - -// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available -topState:function topState(n) { - n = this.conditionStack.length - 1 - Math.abs(n || 0); - if (n >= 0) { - return this.conditionStack[n]; - } else { - return "INITIAL"; - } - }, - -// alias for begin(condition) -pushState:function pushState(condition) { - this.begin(condition); - }, - -// return the number of states currently on the stack -stateStackSize:function stateStackSize() { - return this.conditionStack.length; - }, -options: {"case-insensitive":true,"moduleName":"lexer","moduleType":"js"}, -performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) { -var YYSTATE=YY_START; -switch($avoiding_name_collisions) { -case 0: - if (this.asp_tags) { - this.begin("ST_IN_SCRIPTING"); - return T_OPEN_TAG_WITH_ECHO; - } else { - this.reject(); - } - -break; -case 1: - this.begin("ST_IN_SCRIPTING"); - return T_OPEN_TAG_WITH_ECHO; - -break; -case 2: - if (this.asp_tags) { - this.begin("ST_IN_SCRIPTING"); - return T_OPEN_TAG; - } else { - this.reject(); - } - -break; -case 3: - this.begin("ST_IN_SCRIPTING"); - return T_OPEN_TAG; - -break; -case 4: - if (this.short_tags) { - this.begin("ST_IN_SCRIPTING"); - return T_OPEN_TAG; - } else { - throw new Error('Unauth state'); - this.unput(" 0) { - var char = this.input(); - if (char == '\\') { - this.input(); - } else if ( char == '$' ) { - if ( - this._input[0] == '{' - || IS_LABEL_START(char) - ) { - this.unput(char); - break; - } - } else if (char == '`') { - this.unput(char); - break; - } - } - // yy_.yytext = scan_escape_string(yy_.yytext); - return T_ENCAPSED_AND_WHITESPACE; - -break; -case 22: - var scan = this.matches[0] + this._input; - var eot = scan.length; - var i = 0, eol; - var char; - var lblLen = this.heredoc_label.length; - var found = false, newLine = 1; - - /** edge case : empty here doc **/ - if (scan.substring(0, lblLen) == this.heredoc_label) { - eol = scan[lblLen]; - if ( eol == '\n' || eol == '\r' || eol == ';') { - consume(this, lblLen - 1); - this.popState(); - return T_END_HEREDOC; - } - } - - while(i < eot) { - char = scan[i]; - if (char == '\n' || char == '\r') { - if (char == '\r') { - if (++i < eot) { - char = scan[i]; - if (char !== '\n') { - i--; - } - } - } - // @fixme : check if out of text limits - if (scan.substring(i + 1, i + lblLen + 1) == this.heredoc_label) { - eol = scan[ i + lblLen + 1]; - if ( eol == '\n' || eol == '\r' || eol == ';') { - found = true; - break; - } - } - } - else if (char === '\\') { - char = ++i < eot && scan[i]; - if (char == '\n' || char == '\r') { - i--; - } - } - else if (char == '$') { - char = ++i < eot && scan[i]; - if (char == '{' || IS_LABEL_START(char)) { - i -= 2; - break; - } else continue; - } - else if (char == '{') { - char = ++i < eot && scan[i]; - if (char == '$') { - i -= 2; - break; - } else continue; - } - i++; - } - consume(this, i + 1 - this.matches[0].length); - if (found) this.begin('ST_END_HEREDOC'); - return T_ENCAPSED_AND_WHITESPACE; - -break; -case 23: - var scan = this.matches[0] + this._input; - var eot = scan.length; - var i = 0, eol; - var char; - var lblLen = this.heredoc_label.length; - - /** edge case : empty now doc **/ - if (scan.substring(0, lblLen) == this.heredoc_label) { - eol = scan[lblLen]; - if ( eol == '\n' || eol == '\r' || eol == ';') { - consume(this, lblLen - 1); - this.popState(); - return T_END_HEREDOC; - } - } - - while(i < eot) { - char = scan[i]; - if (char == '\n' || char == '\r') { - if (char == '\r') { - char = ++i < eot && scan[i]; - if (char !== '\n') i--; - } - // @fixme : check if out of text limits - if (scan.substring(i + 1, i + lblLen + 1) == this.heredoc_label) { - eol = scan[ i + lblLen + 1]; - if ( eol == '\n' || eol == '\r' || eol == ';') { - break; - } - } - } - i++; - } - consume(this, i + 1 - this.matches[0].length); - this.begin('ST_END_HEREDOC'); - return T_ENCAPSED_AND_WHITESPACE; - -break; -case 24: - return T_EXIT; - -break; -case 25: - return T_EXIT; - -break; -case 26: - return T_FUNCTION; - -break; -case 27: - return T_CONST; - -break; -case 28: - return T_RETURN; - -break; -case 29: - return T_YIELD_FROM; - -break; -case 30: - return T_YIELD; - -break; -case 31: - return T_TRY; - -break; -case 32: - return T_CATCH; - -break; -case 33: - return T_FINALLY; - -break; -case 34: - return T_THROW; - -break; -case 35: - return T_IF; - -break; -case 36: - return T_ELSEIF; - -break; -case 37: - return T_ENDIF; - -break; -case 38: - return T_ELSE; - -break; -case 39: - return T_WHILE; - -break; -case 40: - return T_ENDWHILE; - -break; -case 41: - return T_DO; - -break; -case 42: - return T_FOR; - -break; -case 43: - return T_ENDFOR; - -break; -case 44: - return T_FOREACH; - -break; -case 45: - return T_ENDFOREACH; - -break; -case 46: - return T_DECLARE; - -break; -case 47: - return T_ENDDECLARE; - -break; -case 48: - return T_INSTANCEOF; - -break; -case 49: - return T_AS; - -break; -case 50: - return T_SWITCH; - -break; -case 51: - return T_ENDSWITCH; - -break; -case 52: - return T_CASE; - -break; -case 53: - return T_DEFAULT; - -break; -case 54: - return T_BREAK; - -break; -case 55: - return T_CONTINUE; - -break; -case 56: - return T_GOTO; - -break; -case 57: - return T_ECHO; - -break; -case 58: - return T_PRINT; - -break; -case 59: - return T_CLASS; - -break; -case 60: - return T_INTERFACE; - -break; -case 61: - return T_TRAIT; - -break; -case 62: - return T_EXTENDS; - -break; -case 63: - return T_IMPLEMENTS; - -break; -case 64: - this.begin('ST_LOOKING_FOR_PROPERTY'); - return T_OBJECT_OPERATOR; - -break; -case 65: - return T_WHITESPACE; - -break; -case 66: - return T_OBJECT_OPERATOR; - -break; -case 67: - return T_STRING; - -break; -case 68: - this.popState(); - this.less(0); - return false; - -break; -case 69: - return T_DOUBLE_COLON; - -break; -case 70: - return T_NS_SEPARATOR; - -break; -case 71: - return T_NEW; - -break; -case 72: - return T_CLONE; - -break; -case 73: - return T_VAR; - -break; -case 74: - return T_INT_CAST; - -break; -case 75: - return T_DOUBLE_CAST; - -break; -case 76: - return T_STRING_CAST; - -break; -case 77: - return T_ARRAY_CAST; - -break; -case 78: - return T_OBJECT_CAST; - -break; -case 79: - return T_BOOL_CAST; - -break; -case 80: - return T_UNSET_CAST; - -break; -case 81: - return T_EVAL; - -break; -case 82: - return T_INCLUDE; - -break; -case 83: - return T_INCLUDE_ONCE; - -break; -case 84: - return T_REQUIRE; - -break; -case 85: - return T_REQUIRE_ONCE; - -break; -case 86: - return T_NAMESPACE; - -break; -case 87: - return T_USE; - -break; -case 88: - return T_INSTEADOF; - -break; -case 89: - return T_GLOBAL; - -break; -case 90: - return T_ISSET; - -break; -case 91: - return T_EMPTY; - -break; -case 92: - return T_HALT_COMPILER; - -break; -case 93: - return T_STATIC; - -break; -case 94: - return T_ABSTRACT; - -break; -case 95: - return T_FINAL; - -break; -case 96: - return T_PRIVATE; - -break; -case 97: - return T_PROTECTED; - -break; -case 98: - return T_PUBLIC; - -break; -case 99: - return T_UNSET; - -break; -case 100: - return T_DOUBLE_ARROW; - -break; -case 101: - return T_LIST; - -break; -case 102: - return T_ARRAY; - -break; -case 103: - return T_CALLABLE; - -break; -case 104: - return T_INC; - -break; -case 105: - return T_DEC; - -break; -case 106: - return T_IS_IDENTICAL; - -break; -case 107: - return T_IS_NOT_IDENTICAL; - -break; -case 108: - return T_IS_EQUAL; - -break; -case 109: - return T_IS_NOT_EQUAL; - -break; -case 110: - return T_IS_SMALLER_OR_EQUAL; - -break; -case 111: - return T_IS_GREATER_OR_EQUAL; - -break; -case 112: - return T_PLUS_EQUAL; - -break; -case 113: - return T_MINUS_EQUAL; - -break; -case 114: - return T_MUL_EQUAL; - -break; -case 115: - return T_DIV_EQUAL; - -break; -case 116: - return T_CONCAT_EQUAL; - -break; -case 117: - return T_MOD_EQUAL; - -break; -case 118: - return T_SL_EQUAL; - -break; -case 119: - return T_SR_EQUAL; - -break; -case 120: - return T_AND_EQUAL; - -break; -case 121: - return T_OR_EQUAL; - -break; -case 122: - return T_XOR_EQUAL; - -break; -case 123: - return T_BOOLEAN_OR; - -break; -case 124: - return T_BOOLEAN_AND; - -break; -case 125: - return T_LOGICAL_OR; - -break; -case 126: - return T_LOGICAL_AND; - -break; -case 127: - return T_LOGICAL_XOR; - -break; -case 128: - return T_SL; - -break; -case 129: - return T_SR; - -break; -case 130: - return T_ELLIPSIS; - -break; -case 131: - return T_COALESCE; - -break; -case 132: - return T_POW_EQUAL; - -break; -case 133: - return T_POW; - -break; -case 134: - return '{'; - -break; -case 135: - // @todo : RESET_DOC_COMMENT(); - if ( - this.conditionStack.length > 2 - && this.conditionStack[this.conditionStack.length - 2] !== 'ST_IN_SCRIPTING' - ) { - // Return to HEREDOC/ST_DOUBLE_QUOTES mode - this.popState(); - } - return '}'; - -break; -case 136: - return T_CLASS_C; - -break; -case 137: - return T_TRAIT_C; - -break; -case 138: - return T_FUNC_C; - -break; -case 139: - return T_METHOD_C; - -break; -case 140: - return T_LINE; - -break; -case 141: - return T_FILE; - -break; -case 142: - return T_DIR; - -break; -case 143: - return T_NS_C; - -break; -case 144: - this.less(yy_.yyleng - 1); - this.popState(); - this.begin('ST_IN_SCRIPTING'); - return T_STRING_VARNAME; - -break; -case 145: - this.popState(); - this.less(0); - return false; - -break; -case 146: /* Offset could be treated as a long */ - return T_NUM_STRING; - -break; -case 147: /* Offset must be treated as a string */ - return T_NUM_STRING; - -break; -case 148: - this.popState(); - return ']'; - -break; -case 149: - return yy_.yytext; - -break; -case 150: - return T_ENCAPSED_AND_WHITESPACE; - -break; -case 151: - return T_STRING; - -break; -case 152: - return T_DNUMBER; - -break; -case 153: - return T_LNUMBER; - -break; -case 154: - return T_LNUMBER; - -break; -case 155: - if (yy_.yyleng < MAX_LENGTH_OF_LONG - 1) { - return T_LNUMBER; - } else { - if ( - yy_.yyleng == MAX_LENGTH_OF_LONG - && yy_.yytext < long_min_digits - ) { - return T_LNUMBER; - } - return T_DNUMBER; - } - -break; -case 156: - while(this._input.length > 0) { - var char = this.input(); - if ( - char == '\r' - || char == '\n' - || char == '\r\n' - ) { - break; - } else if ( - char == '?' - && this._input[0] == '>' - ) { - // end of PHP tag - this.unput(char); - break; - } else if ( - this.asp_tags - && char == '%' - && this._input[0] == '>' - ) { - // end of PHP(ASP-Like) tag - this.unput(char); - break; - } - } - return T_COMMENT; - -break; -case 157: - var type = T_COMMENT; - if (yy_.yytext.length > 2) { - type = T_DOC_COMMENT; - } - while(this._input.length > 0) { - var char = this.input(); - if ( - char == '*' - && this._input[0] == '/' - ) { - this.input(); - break; - } - } - return type; - -break; -case 158: - return yy_.yytext; - -break; -case 159: - this.reject(); - -break; -} -}, -rules: [/^(?:<%=)/i,/^(?:<\?=)/i,/^(?:<%)/i,/^(?:<\?php([ \t]|((\r\n|\n|\r))))/i,/^(?:<\?)/i,/^(?:([^]))/i,/^(?:\?>((\r\n|\n|\r))?)/i,/^(?:%>((\r\n|\n|\r))?)/i,/^(?:\$\{)/i,/^(?:\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)->[a-zA-Z_\x7f-\xff])/i,/^(?:\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\[)/i,/^(?:\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*))/i,/^(?:b?['])/i,/^(?:b?["])/i,/^(?:b?<<<([ \t]*)(([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)|([']([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)['])|(["]([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)["]))((\r\n|\n|\r)))/i,/^(?:[`])/i,/^(?:([^]))/i,/^(?:\{\$)/i,/^(?:["])/i,/^(?:[`])/i,/^(?:([^]))/i,/^(?:([^]))/i,/^(?:([^]))/i,/^(?:([^]))/i,/^(?:exit\b)/i,/^(?:die\b)/i,/^(?:function\b)/i,/^(?:const\b)/i,/^(?:return\b)/i,/^(?:yield from\b)/i,/^(?:yield\b)/i,/^(?:try\b)/i,/^(?:catch\b)/i,/^(?:finally\b)/i,/^(?:throw\b)/i,/^(?:if\b)/i,/^(?:elseif\b)/i,/^(?:endif\b)/i,/^(?:else\b)/i,/^(?:while\b)/i,/^(?:endwhile\b)/i,/^(?:do\b)/i,/^(?:for\b)/i,/^(?:endfor\b)/i,/^(?:foreach\b)/i,/^(?:endforeach\b)/i,/^(?:declare\b)/i,/^(?:enddeclare\b)/i,/^(?:instanceof\b)/i,/^(?:as\b)/i,/^(?:switch\b)/i,/^(?:endswitch\b)/i,/^(?:case\b)/i,/^(?:default\b)/i,/^(?:break\b)/i,/^(?:continue\b)/i,/^(?:goto\b)/i,/^(?:echo\b)/i,/^(?:print\b)/i,/^(?:class\b)/i,/^(?:interface\b)/i,/^(?:trait\b)/i,/^(?:extends\b)/i,/^(?:implements\b)/i,/^(?:->)/i,/^(?:([ \n\r\t]+)+)/i,/^(?:->)/i,/^(?:([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*))/i,/^(?:([^]))/i,/^(?:::)/i,/^(?:\\)/i,/^(?:new\b)/i,/^(?:clone\b)/i,/^(?:var\b)/i,/^(?:\(([ \t]*)(int|integer)([ \t]*)\))/i,/^(?:\(([ \t]*)(real|double|float)([ \t]*)\))/i,/^(?:\(([ \t]*)(string|binary)([ \t]*)\))/i,/^(?:\(([ \t]*)array([ \t]*)\))/i,/^(?:\(([ \t]*)object([ \t]*)\))/i,/^(?:\(([ \t]*)(bool|boolean)([ \t]*)\))/i,/^(?:\(([ \t]*)(unset)([ \t]*)\))/i,/^(?:eval\b)/i,/^(?:include\b)/i,/^(?:include_once\b)/i,/^(?:require\b)/i,/^(?:require_once\b)/i,/^(?:namespace\b)/i,/^(?:use\b)/i,/^(?:insteadof\b)/i,/^(?:global\b)/i,/^(?:isset\b)/i,/^(?:empty\b)/i,/^(?:__halt_compiler\b)/i,/^(?:static\b)/i,/^(?:abstract\b)/i,/^(?:final\b)/i,/^(?:private\b)/i,/^(?:protected\b)/i,/^(?:public\b)/i,/^(?:unset\b)/i,/^(?:=>)/i,/^(?:list\b)/i,/^(?:array\b)/i,/^(?:callable\b)/i,/^(?:\+\+)/i,/^(?:--)/i,/^(?:===)/i,/^(?:!==)/i,/^(?:==)/i,/^(?:!=|<>)/i,/^(?:<=)/i,/^(?:>=)/i,/^(?:\+=)/i,/^(?:-=)/i,/^(?:\*=)/i,/^(?:\/=)/i,/^(?:\.=)/i,/^(?:%=)/i,/^(?:<<=)/i,/^(?:>>=)/i,/^(?:&=)/i,/^(?:\|=)/i,/^(?:\^=)/i,/^(?:\|\|)/i,/^(?:&&)/i,/^(?:OR\b)/i,/^(?:AND\b)/i,/^(?:XOR\b)/i,/^(?:<<)/i,/^(?:>>)/i,/^(?:\.\.\.)/i,/^(?:\?\?)/i,/^(?:\*\*=)/i,/^(?:\*\*)/i,/^(?:\{)/i,/^(?:\})/i,/^(?:__CLASS__\b)/i,/^(?:__TRAIT__\b)/i,/^(?:__FUNCTION__\b)/i,/^(?:__METHOD__\b)/i,/^(?:__LINE__\b)/i,/^(?:__FILE__\b)/i,/^(?:__DIR__\b)/i,/^(?:__NAMESPACE__\b)/i,/^(?:([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[[}])/i,/^(?:([^]))/i,/^(?:[0]|([1-9][0-9]*))/i,/^(?:([0-9]+)|(0x[0-9a-fA-F]+)|(0b[01]+))/i,/^(?:\])/i,/^(?:([;:,.\[\]()|^&+-\/*=%!~$<>?@])|[{}"`])/i,/^(?:[ \n\r\t\\'#])/i,/^(?:([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*))/i,/^(?:(((([0-9]+)|(([0-9]*\.[0-9]+)|([0-9]+\.[0-9]*)))[eE][+-]?([0-9]+)))|(([0-9]*\.[0-9]+)|([0-9]+\.[0-9]*)))/i,/^(?:(0b[01]+))/i,/^(?:(0x[0-9a-fA-F]+))/i,/^(?:([0-9]+))/i,/^(?:#|\/\/)/i,/^(?:\/\*\*([ \n\r\t]+)|\/\*)/i,/^(?:([;:,.\[\]()|^&+-\/*=%!~$<>?@]))/i,/^(?:([^]))/i], -conditions: {"ST_LOOKING_FOR_VARNAME":{"rules":[144,145],"inclusive":false},"ST_NOWDOC":{"rules":[23],"inclusive":false},"ST_END_HEREDOC":{"rules":[16],"inclusive":false},"ST_HEREDOC":{"rules":[8,9,10,11,17,22],"inclusive":false},"ST_BACKQUOTE":{"rules":[8,9,10,11,17,19,21],"inclusive":false},"ST_DOUBLE_QUOTES":{"rules":[8,9,10,11,17,18,20],"inclusive":false},"ST_LOOKING_FOR_PROPERTY":{"rules":[66,67,68],"inclusive":false},"ST_VAR_OFFSET":{"rules":[11,146,147,148,149,150,151,159],"inclusive":false},"ST_IN_SCRIPTING":{"rules":[6,7,11,12,13,14,15,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,151,152,153,154,155,156,157,158,159],"inclusive":false},"INITIAL":{"rules":[0,1,2,3,4,5],"inclusive":true}} -}); -return lexer; -})(); - -// defines if all tokens must be retrieved (used by token_get_all only) -lexer.all_tokens = true; -// enables the evald mode (ignore opening tags) -lexer.mode_eval = false; -// disables by default asp tags mode -lexer.asp_tags = false; -// enables by default short tags mode -lexer.short_tags = true; -// change lexer algorithm -var lex = lexer.lex; -lexer.lex = function() { - var token = lex.call(this); - if (!this.all_tokens) { - while( - token === T_WHITESPACE // ignore white space - || token === T_COMMENT // ignore single lines comments - || token === T_DOC_COMMENT // ignore doc comments - || ( - !this.mode_eval // ignore open/close tags - && ( - token === T_OPEN_TAG - ) - ) - ) { - token = lex.call(this); - } - if (!this.mode_eval && token == T_OPEN_TAG_WITH_ECHO) { - // open tag with echo statement - return T_ECHO; - } - } - return token; -}; - -// fix of input algorithm @see https://github.com/zaach/jison-lex/pull/10 -lexer.input = function() { - var ch = this._input[0]; - if ( ch == '\r' && this._input[1] == '\n' ) { - ch += '\n'; - this.yyleng++; - this.offset++; - this._input = this._input.slice(1); - if (this.options.ranges) { - this.yylloc.range[1]++; - } - } - this.yytext += ch; - this.yyleng++; - this.offset++; - this.match += ch; - this.matched += ch; - var lines = ch.match(/(?:\r\n?|\n).*/g); - if (lines) { - this.yylineno++; - this.yylloc.last_line++; - } else { - this.yylloc.last_column++; - } - if (this.options.ranges) { - this.yylloc.range[1]++; - } - - this._input = this._input.slice(1); - return ch; -}; - -// fix of eating just one char on any char mode (and counting lines twice on windows) -lexer.test_match = function (match, indexed_rule) { - var token, - lines, - backup; - - if (this.options.backtrack_lexer) { - // save context - backup = { - yylineno: this.yylineno, - yylloc: { - first_line: this.yylloc.first_line, - last_line: this.last_line, - first_column: this.yylloc.first_column, - last_column: this.yylloc.last_column - }, - yytext: this.yytext, - match: this.match, - matches: this.matches, - matched: this.matched, - yyleng: this.yyleng, - offset: this.offset, - _more: this._more, - _input: this._input, - yy: this.yy, - conditionStack: this.conditionStack.slice(0), - done: this.done - }; - if (this.options.ranges) { - backup.yylloc.range = this.yylloc.range.slice(0); - } - } - - lines = match[0].match(/(?:\r\n?|\n).*/g); - if (lines) { - this.yylineno += lines.length; - if (match[0].length === 1 && this._input[0] === '\r' && this._input[1] === '\n') { - match[0] += '\n'; // make it match entire line return (windows) - } - } - this.yylloc = { - first_line: this.yylloc.last_line, - last_line: this.yylineno + 1, - first_column: this.yylloc.last_column, - last_column: lines ? - lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : - this.yylloc.last_column + match[0].length - }; - this.yytext += match[0]; - this.match += match[0]; - this.matches = match; - this.yyleng = this.yytext.length; - if (this.options.ranges) { - this.yylloc.range = [this.offset, this.offset += this.yyleng]; - } - this._more = false; - this._backtrack = false; - this._input = this._input.slice(match[0].length); - this.matched += match[0]; - token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); - if (this.done && this._input) { - this.done = false; - } - if (token) { - return token; - } else if (this._backtrack) { - // recover context - for (var k in backup) { - this[k] = backup[k]; - } - return false; // rule action called reject() implying the next rule should be tested instead. - } - return false; -}; - -// FORCE TO CHANGE THE INITIAL STATE IN EVAL MODE -var setInput = lexer.setInput; -lexer.setInput = function (input, yy) { - setInput.call(this, input, yy); - if ( - !this.all_tokens && this.mode_eval - ) { - this.conditionStack = ['ST_IN_SCRIPTING']; - } -}; - -module.exports = lexer; \ No newline at end of file diff --git a/bin/test.js b/bin/test.js deleted file mode 100644 index 295d5408f..000000000 --- a/bin/test.js +++ /dev/null @@ -1,345 +0,0 @@ -#!/usr/bin/env node - -/** - * Copyright (C) 2014 Glayzzle (BSD3 License) - * @authors https://github.com/glayzzle/php-parser/graphs/contributors - * @url http://glayzzle.com - */ - -var util = require('util'); -var fs = require('fs'); -var path = require('path'); - -var engine = require('../src/index'); -engine = new engine(); - -engine.lexer.short_tags = true; - -// help screen -function printHelp() { - console.log('Usage: test [options] [-f] '); - console.log(''); - console.log(' -f Parse and test the specified file'); - console.log(' -d Parse each file in the specified path'); - console.log(' -m Run mocha tests on the specified path'); - console.log(' -r Use recursivity with the specified path'); - console.log(' -e Eval the specified input and shows AST'); - console.log(' -v Enable verbose mode and show debug'); - console.log(' -s Silent error mode, and try to suppress errors'); - console.log(' --asp_short Test with short tags'); - console.log(' -h, --help Print help and exit'); -} - - -// aborts the execution with the specified error message -function abort(message) { - console.error(message); - process.exit(1); -} - -/* Arguments */ -var options = { - filename: null, - path: null, - recursive: false, - evalCode: false, - aspShort: false, - mocha: false -}; - -var args = process.argv.slice(2); // Trim 'node' and the script path. - - -function isOption(arg) { - return (/^-/).test(arg); -} - -function nextArg() { - args.shift(); -} - -// Reading arguments -while (args.length > 0 && isOption(args[0])) { - switch(args[0]) { - case '-f': - nextArg(); - options.filename = args[0]; - break; - - case '-e': - nextArg(); - options.evalCode = args[0]; - break; - - case '--asp_short': - engine.lexer.asp_tags = true; - options.aspShort = true; - break; - - case '--debug': - case '-v': - engine.parser.locations = true; - engine.parser.debug = true; - break; - - case '-s': - engine.parser.suppressErrors = true; - break; - - case '-d': - nextArg(); - options.path = args[0]; - break; - - case '-m': - nextArg(); - options.mocha = args[0]; - break; - - case '-r': - options.recusive = true; - break; - - case '-h': - case '--help': - printHelp(); - process.exit(0); - break; - - default: - abort('Unknown option: ' + args[0] + '.'); - } - nextArg(); -} - -// Checking last parameters -if ( args.length > 0 ) { - if ( args.length == 1 && !options.filename ) { - options.filename = args[0]; - } else { - abort('Too many arguments.'); - } -} -if ( !options.filename && !options.path && !options.evalCode && !options.mocha ) { - abort('Expecting a filename or a path.'); -} - -process.env.DEBUG = options.debug; - -// Load tests handlers -var engines = [ - require('./formats/parser') - , require('./formats/token') - , require('./formats/php') - , require('./formats/phpt') - , require('./formats/ast') -]; - -// gets the extension of the specified filename -function getExtension(filename) { - var i = filename.lastIndexOf('.'); - return (i < 0) ? '' : filename.substr(i); -} - -// run a test over the specified file -function test(filename) { - if (engine.parser.debug) { - console.log(' + ' + filename); - } - try { - if (options.ast) { - return engines[4].run( - filename - , engine - ); - } - var extension = getExtension(filename); - var result = false, found = false; - for(var i = 0; i < engines.length; i++) { - if (engines[i].handles(filename, extension)) { - found = true; - if (engines[i].explode) { - result = engines[i].run( - fs.readFileSync(filename).toString().split( - /[\r\n]/ - ) - , filename - , engine - ); - } else { - result = engines[i].run(filename, engine); - } - if (!result) { - if (engine.parser.debug) { - abort('Test "' + filename + '" does not pass !'); - break; - } else { - throw new Error('Test "' + filename + '" does not pass !'); - } - } - } - } - if (!found) { - if (engine.parser.debug) { - console.info('\n(i) IGNORED : unrecognized extension "'+getExtension(filename)+'" for ' + filename); - } - return false; - } else { - return result; - } - } catch(e) { - console.error( (e.stack || e) + '\n' ); - throw e; - return false; - } -} - -if (options.mocha) { - var Mocha = require('mocha'), path = require('path'); - - // Instantiate a Mocha instance. - var mocha = new Mocha(); - - // Add each .js file to the mocha instance - fs.readdirSync(options.mocha).filter(function(file){ - // Only keep the .js files - return file.substr(-3) === '.js'; - }).forEach(function(file){ - mocha.addFile( - path.join(options.mocha, file) - ); - }); - - // Run the tests. - mocha.run(function(failures){ - if (failures) { - process.on('exit', function () { - process.exit(failures); // exit with non-zero status if there were failures - }); - } else { - runTests(); - } - }); -} else runTests(); - -// run tests -function runTests() { - - console.log('\n*** START TESTING ***\n'); - if (options.evalCode) { - var EOF = engine.lexer.EOF; - engine.lexer.mode_eval = true; - engine.lexer.all_tokens = false; - engine.lexer.setInput(options.evalCode); - var token = engine.lexer.lex() || EOF; - var names = engine.tokens.values; - var tokens = []; - while(token != EOF) { - if (names[token]) { - tokens.push(names[token]); - } else { - tokens.push(token); - } - token = engine.lexer.lex() || EOF; - } - console.log('-- TOKENS : '); - console.log(tokens.join(' ')); - - var ast = engine.parser.parse(options.evalCode); - console.log('-- AST : '); - console.log( - util.inspect( - ast, { - showHidden: false, - depth: 20, - colors: true - } - ) - ); - - } else if (options.filename) { - if (!test(options.filename)) { - abort('Error: test FAILED !!!'); - } else { - console.log('Success'); - } - } else if (options.path) { - - var files = []; - var scanFiles = function(path) { - var items = fs.readdirSync(path); - for(var i = 0; i < items.length; i ++) { - var file = items[i]; - if (file[0] != '.') { - var stat = fs.statSync(path + file); - if (!stat.isDirectory()) { - files.push(path + file); - } else if (options.recusive) { - scanFiles(path + file + '/'); - } - } - } - }; - - console.log('Scan files ' + options.path); - scanFiles(options.path); - console.log('Found ' + files.length + ' items'); - - var stats = { - time: process.hrtime(), - progress: 0, - code: 0, - errors: 0 - }; - - function secondsToTime(secs) - { - secs = Math.round(secs); - var hours = Math.floor(secs / (60 * 60)); - if (hours < 10) hours = '0' + hours; - var divisor_for_minutes = secs % (60 * 60); - var minutes = Math.floor(divisor_for_minutes / 60); - if (minutes < 10) minutes = '0' + minutes; - var divisor_for_seconds = divisor_for_minutes % 60; - var seconds = Math.ceil(divisor_for_seconds); - if (seconds < 10) seconds = '0' + seconds; - return hours + ':' + minutes + ':' + seconds; - } - // running - for(var i = 0; i < files.length; i++) { - var file = files[i]; - if (i / files.length * 100 > stats.progress + 2) { - stats.progress = i / files.length * 100; - var now = process.hrtime(stats.time); - var remain = (now[0] / stats.progress) * (100 - stats.progress); - console.log( - 'Progress ', - Math.round(stats.progress) + '%', - ' remains ', - secondsToTime(remain) - ); - } - try { - test(file); - } catch(e) { - stats.code = 1; - stats.errors ++; - console.error('Error on ' + file); - console.error(e); - } - } - - var duration = process.hrtime(stats.time); - console.log('\n--------------------------------------'); - console.log('Tests duration : ' + duration[0] +'sec'); - - if (stats.code === 0) { - console.log('I AM HAPPY !'); - } else { - console.log('Found ' + stats.errors + ' error(s)'); - } - - process.exit(stats.code); - } - -} diff --git a/dist/php-parser.js b/dist/php-parser.js index d381c9e75..b7be59dde 100644 --- a/dist/php-parser.js +++ b/dist/php-parser.js @@ -1,4 +1,4 @@ -/*! php-parser - BSD3 License - 2016-12-27 */ +/*! php-parser - BSD3 License - 2016-12-28 */ 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 too bad this.expect(this.tok.T_STRING); } - } else { - this.expect([ - this.tok.T_AS, - this.tok.T_INSTEADOF - ]); + + return node('traitalias', trait, method, alias, flags) } - return node(origin, act, target, flags); + + // handle errors + this.expect([this.tok.T_AS, this.tok.T_INSTEADOF]); + return node('traitalias', trait, method, null, null); } }; -},{}],52:[function(require,module,exports){ +},{}],77:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors * @url http://glayzzle.com */ + +var docSplit = /^(\s*\*[ \t]*|[ \t]*)(.*)$/gm; + module.exports = { /** - * Comments with // or # + * Comments with // or # or / * ... * / */ read_comment: function() { - var result = this.node('comment'); - var input = [this.text()]; - while(this.nextWithComments().token === this.tok.T_COMMENT) { - input.push(this.text()); - } - return result(input); + var result = this.node('doc'); + var lines = []; + do { + var line = this.text(); + if (line[0] === '#') { + line = line.substring(1); + } else { + line = line.substring(2); + if (line.substring(line.length - 2) === '*/') { + line = line.substring(0, line.length - 2); + } + } + lines.push(line.trim()); + } while(this.nextWithComments().token === this.tok.T_COMMENT); + return result(false, lines); }, /** - * Comments with / ** ** / + * Comments with / ** ... * / */ read_doc_comment: function() { - var result = this.node('doc')(this.text()); + var result = this.node('doc'); + var text = this.text(); + text = text.substring(2, text.length - 2); + var lines = []; + text = text.split(docSplit); + for(var i = 2; i < text.length; i += 3) { + lines.push(text[i].trim()); + } this.nextWithComments(); - return result; + return result(true, lines); } }; -},{}],53:[function(require,module,exports){ +},{}],78:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -3883,7 +4606,9 @@ module.exports = { if (this.next().token !== ':') { trueArg = this.read_expr(); } - this.expect(':').next(); + if (this.expect(':')) { + this.next(); + } return ['retif', expr, trueArg, this.read_expr()]; } return expr; @@ -3924,7 +4649,9 @@ module.exports = { case '(': var expr = this.next().read_expr(); - this.expect(')').next(); + if (this.expect(')')) { + this.next(); + } // handle dereferencable if (this.token === this.tok.T_OBJECT_OPERATOR) { @@ -3947,9 +4674,14 @@ module.exports = { return result(expr); case this.tok.T_LIST: - var result = this.node('list'); - this.next().expect('(').next(); + var result = this.node('list'), assign = null; var isInner = this.innerList; + if (!isInner) { + assign = this.node('assign'); + } + if (this.next().expect('(')) { + this.next(); + } if (!this.innerList) this.innerList = true; var assignList = this.read_assignment_list(); @@ -3967,14 +4699,24 @@ module.exports = { 'Fatal Error : Cannot use empty list on line ' + this.lexer.yylloc.first_line ); } - this.expect(')').next(); + if (this.expect(')')) { + this.next(); + } if (!isInner) { this.innerList = false; - this.expect('=').next(); - return result(assignList, this.read_expr()); + if (this.expect('=')) { + return assign( + result(assignList), + this.next().read_expr(), + '=' + ); + } else { + // fallback : list($a, $b); + return result(assignList); + } } else { - return result(assignList, null); + return result(assignList); } case this.tok.T_CLONE: @@ -3995,16 +4737,24 @@ module.exports = { case this.tok.T_ISSET: var result = this.node('isset'); - this.next().expect('(').next(); + if (this.next().expect('(')) { + this.next(); + } var args = this.read_list(this.read_expr, ','); - this.expect(')').next(); + if (this.expect(')')) { + this.next(); + } return result(args); case this.tok.T_EMPTY: var result = this.node('empty'); - this.next().expect('(').next(); + if (this.next().expect('(')) { + this.next(); + } var arg = this.read_expr(); - this.expect(')').next(); + if (this.expect(')')) { + this.next(); + } return result([arg]); case this.tok.T_INCLUDE: @@ -4033,9 +4783,13 @@ module.exports = { case this.tok.T_EVAL: var result = this.node('eval'); - this.next().expect('(').next(); + if (this.next().expect('(')) { + this.next(); + } var expr = this.read_expr(); - this.expect(')').next(); + if (this.expect(')')) { + this.next(); + } return result(expr); case this.tok.T_INT_CAST: @@ -4067,7 +4821,9 @@ module.exports = { if ( this.next().token === '(' ) { if (this.next().token !== ')') { status = this.read_expr(); - this.expect(')').next(); + if (this.expect(')')) { + this.next(); + } } else { this.next(); } @@ -4149,11 +4905,13 @@ module.exports = { case this.tok.T_SR_EQUAL: return ['set', expr, ['bin', '>>', expr, this.next().read_expr()]]; case this.tok.T_INC: + var result = this.node('post'); this.next(); - return ['post', '+', expr]; + return result('+', expr); case this.tok.T_DEC: + var result = this.node('post'); this.next(); - return ['post', '-', expr]; + return result('+', expr); } } else if (this.is('SCALAR')) { expr = this.read_scalar(); @@ -4189,21 +4947,21 @@ module.exports = { var result = this.node('new'); if (this.token === this.tok.T_CLASS) { // Annonymous class declaration - var propExtends = false, propImplements = false; + var propExtends = null, propImplements = null, body = null; if (this.next().token == this.tok.T_EXTENDS) { propExtends = this.next().read_namespace_name(); } if (this.token == this.tok.T_IMPLEMENTS) { - propImplements = this.next().read_list( - this.read_namespace_name, - ',' - ); + propImplements = this.next().read_name_list(); + } + if (this.expect('{')) { + body = this.next().read_class_body(); } return result( false // class name => false : means it's an annonymous class ,propExtends ,propImplements - ,this.expect('{').next().read_class_body() + ,body ); } else { // Already existing class @@ -4266,7 +5024,7 @@ module.exports = { } }; -},{}],54:[function(require,module,exports){ +},{}],79:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -4301,18 +5059,21 @@ module.exports = { * ``` */ ,read_function: function(closure, flag) { - var result = this.node( - this.read_function_declaration(closure ? 1 : flag ? 2 : 0) + var result = this.read_function_declaration( + closure ? 1 : (flag ? 2 : 0) ); if (flag && flag[2] == 1) { - result = result(flag); - this.expect(';').nextWithComments(); + // abstract function : + result.parseFlags(flag); + if (this.expect(';')) { + this.nextWithComments(); + } } else { - var body = this.expect('{').read_code_block(false); + if (this.expect('{')) { + result.body = this.read_code_block(false); + } if (flag) { - result = result(body, flag); - } else { - result = result(body); + result.parseFlags(flag); } } return result; @@ -4331,24 +5092,30 @@ module.exports = { nodeName = 'method'; } var result = this.node(nodeName); - this.expect(this.tok.T_FUNCTION); - var isRef = this.next().is_reference(); + if (this.expect(this.tok.T_FUNCTION)) { + this.next(); + } + var isRef = this.is_reference(); var name = false, use = [], returnType = false; if (type !== 1) { - name = this.expect(this.tok.T_STRING).text(); - this.next(); + if (this.expect(this.tok.T_STRING)) { + name = this.text(); + this.next(); + } } - this.expect('(').next(); + if (this.expect('(')) this.next(); var params = this.read_parameter_list(); - this.expect(')').next(); + if (this.expect(')')) this.next(); if (type === 1 && this.token === this.tok.T_USE) { - use = this.next().expect('(').next().read_list(this.read_lexical_var, ','); - this.expect(')').next(); + if (this.next().expect('(')) this.next(); + use = this.read_list(this.read_lexical_var, ','); + if (this.expect(')')) this.next(); } if (this.token === ':') { returnType = this.next().read_type(); } if (type === 1) { + // closure return result(params, isRef, use, returnType); } return result(name, params, isRef, returnType); @@ -4402,13 +5169,17 @@ module.exports = { * @see https://github.com/php/php-src/blob/493524454d66adde84e00d249d607ecd540de99f/Zend/zend_language_parser.y#L640 */ ,read_parameter: function() { - var node = this.node('param'); + var node = this.node('parameter'), + name = null, + value = null; var type = this.read_type(); var isRef = this.is_reference(); var isVariadic = this.is_variadic(); - var name = this.expect(this.tok.T_VARIABLE).text(); - var value = null; - if (this.next().token == '=') { + if (this.expect(this.tok.T_VARIABLE)) { + name = this.text(); + this.next(); + } + if (this.token == '=') { value = this.next().read_expr(); } return node(name, type, value, isRef, isVariadic); @@ -4420,7 +5191,7 @@ module.exports = { */ ,read_function_argument_list: function() { var result = []; - this.expect('(').next(); + if (this.expect('(')) this.next(); if (this.token !== ')') { while(this.token != this.EOF) { result.push(this.read_argument_list()); @@ -4429,7 +5200,7 @@ module.exports = { } else break; } } - this.expect(')').next(); + if (this.expect(')')) this.next(); return result; } /** @@ -4466,7 +5237,7 @@ module.exports = { } }; -},{}],55:[function(require,module,exports){ +},{}],80:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -4475,207 +5246,258 @@ module.exports = { module.exports = { /** + * Reads an IF statement + * * ```ebnf * if ::= '(' expr ')' ':' ... * ``` */ read_if: function() { - var result = this.node('if'); - var cond = this.read_if_expr(); - var body = null; - var elseCond = false; + var result = this.node('if'), + body = null, + alternate = null, + shortForm = false, + test = null; + test = this.read_if_expr(); if (this.token === ':') { + shortForm = true; this.next(); - body = []; + body = this.node('block'); + var items = []; while(this.token != this.EOF && this.token !== this.tok.T_ENDIF) { this.ignoreComments(); if (this.token === this.tok.T_ELSEIF) { - elseCond = this.next().read_elseif_short(); + alternate = this.next().read_elseif_short(); break; } else if (this.token === this.tok.T_ELSE) { - elseCond = this.next().read_else_short(); + alternate = this.next().read_else_short(); break; } - body.push(this.read_inner_statement()); + items.push(this.read_inner_statement()); } - this.ignoreComments().expect(this.tok.T_ENDIF).next().expectEndOfStatement(); + body = body(null, items); + if (this.ignoreComments().expect(this.tok.T_ENDIF)) this.next(); + this.expectEndOfStatement(); } else { body = this.read_statement(); this.ignoreComments(); if (this.token === this.tok.T_ELSEIF) { - elseCond = this.next().read_if(); + alternate = this.next().read_if(); } else if (this.token === this.tok.T_ELSE) { - elseCond = this.next().read_statement(); + alternate = this.next().read_statement(); } } - return result(cond, body, elseCond); + return result(test, body, alternate, shortForm); }, /** * reads an if expression : '(' expr ')' */ read_if_expr: function() { - this.expect('(').next(); + if (this.expect('(')) this.next(); var result = this.read_expr(); - this.expect(')').next(); + if (this.expect(')')) this.next(); return result; }, /** * reads an elseif (expr): statements */ read_elseif_short: function() { - var result = this.node('if'); - var cond = this.read_if_expr(); - this.expect(':').next(); - var body = []; - var elseCond = false; - + var result = this.node('if'), + alternate = null, + test = null, + body = null, + items = []; + test = this.read_if_expr(); + if (this.expect(':')) this.next(); + body = this.node('block'); while(this.token != this.EOF && this.token !== this.tok.T_ENDIF) { if (this.token === this.tok.T_ELSEIF) { - elseCond = this.next().read_elseif_short(); + alternate = this.next().read_elseif_short(); break; } else if (this.token === this.tok.T_ELSE) { - elseCond = this.next().read_else_short(); + alternate = this.next().read_else_short(); break; } - body.push(this.read_inner_statement()); + items.push(this.read_inner_statement()); } - - return result(cond, body, elseCond); + body = body(null, items); + return result(test, body, alternate, true); }, /** * */ read_else_short: function() { - this.expect(':').next(); - var body = []; + if (this.expect(':')) this.next(); + var body = this.node('block'), items = []; while(this.token != this.EOF && this.token !== this.tok.T_ENDIF) { - body.push(this.read_inner_statement()); + items.push(this.read_inner_statement()); } - return body; + return body(null, items); } }; -},{}],56:[function(require,module,exports){ +},{}],81:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors * @url http://glayzzle.com */ - +"use strict"; module.exports = { - /** - * Reads a short form of tokens - */ - read_short_form: function(token) { - var body = []; - this.expect(':').next(); - while(this.token != this.EOF && this.token !== token) { - body.push(this.read_inner_statement()); - } - this.expect(token).next().expectEndOfStatement(); - return body; - } /** * Reads a while statement + * ```ebnf + * while ::= T_WHILE (statement | ':' inner_statement_list T_ENDWHILE ';') + * ``` + * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L587 + * @return {While} */ - ,read_while: function() { - var result = this.node('while'); - this.expect('(').next(); - var cond = this.read_expr(); - this.expect(')').next(); - var body = []; + read_while: function() { + var result = this.node('while'), + test = null, + body = null, + shortForm = false + ; + if (this.expect('(')) this.next(); + test = this.read_expr(); + if (this.expect(')')) this.next(); if (this.token === ':') { + shortForm = true; body = this.read_short_form(this.tok.T_ENDWHILE); } else { body = this.read_statement(); } - return result(cond, body); + return result(test, body, shortForm); } + /** + * Reads a do / while loop + * ```ebnf + * do ::= T_DO statement T_WHILE '(' expr ')' ';' + * ``` + * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L423 + * @return {Do} + */ ,read_do: function() { - var result = this.node('do'); - var body = this.read_statement(); - this.expect(this.tok.T_WHILE).next().expect('(').next(); - var cond = this.read_expr(); - this.expect(')').next().expect(';').next(); - return result(cond, body); + var result = this.node('do'), + test = null, + body = null + ; + body = this.read_statement(); + if (this.expect(this.tok.T_WHILE)) { + if (this.next().expect('(')) this.next(); + test = this.read_expr(); + if (this.expect(')')) this.next(); + if (this.expect(';')) this.next(); + } + return result(test, body); } + /** + * Read a for incremental loop + * ```ebnf + * for ::= T_FOR '(' for_exprs ';' for_exprs ';' for_exprs ')' for_statement + * for_statement ::= statement | ':' inner_statement_list T_ENDFOR ';' + * for_exprs ::= expr? (',' expr)* + * ``` + * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L425 + * @return {For} + */ ,read_for: function() { - var result = this.node('for'); - this.expect('(').next(); - var expr1 = null, expr2 = null, expr3 = null; + var result = this.node('for'), + init = [], + test = [], + increment = [], + body = null, + shortForm = false; + if (this.expect('(')) this.next(); if (this.token !== ';') { - expr1 = this.read_list(this.read_expr, ','); - this.expect(';').next(); + init = this.read_list(this.read_expr, ','); + if (this.expect(';')) this.next(); } else { this.next(); } if (this.token !== ';') { - expr2 = this.read_list(this.read_expr, ','); - this.expect(';').next(); + test = this.read_list(this.read_expr, ','); + if (this.expect(';')) this.next(); } else { this.next(); } if (this.token !== ')') { - expr3 = this.read_list(this.read_expr, ','); - this.expect(')').next(); + increment = this.read_list(this.read_expr, ','); + if (this.expect(')')) this.next(); } else { this.next(); } - var body = null; if (this.token === ':') { + shortForm = true; body = this.read_short_form(this.tok.T_ENDFOR); } else { body = this.read_statement(); } - return result(expr1, expr2, expr3, body); + return result(init, test, increment, body, shortForm); } /** + * Reads a foreach loop * ```ebnf * foreach ::= '(' expr T_AS foreach_variable (T_DOUBLE_ARROW foreach_variable)? ')' statement * ``` + * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L438 + * @return {Foreach} */ ,read_foreach: function() { - var result = this.node('foreach'); - this.expect('(').next(); - var expr = this.read_expr(); - this.expect(this.tok.T_AS).next(); - var item = this.read_foreach_variable(), - key = false; - if (this.token === this.tok.T_DOUBLE_ARROW) { - key = item; - item = this.next().read_foreach_variable(); + var result = this.node('foreach'), + source = null, + key = null, + value = null, + body = null, + shortForm = false; + if (this.expect('(')) this.next(); + source = this.read_expr(); + if (this.expect(this.tok.T_AS)) { + this.next(); + value = this.read_foreach_variable(); + if (this.token === this.tok.T_DOUBLE_ARROW) { + key = value; + value = this.next().read_foreach_variable(); + } } - this.expect(')').next(); - var body = []; + + if (this.expect(')')) this.next(); + if (this.token === ':') { + shortForm = true; body = this.read_short_form(this.tok.T_ENDFOREACH); } else { body = this.read_statement(); } - return result(expr, key, item, body); + return result(source, key, value, body, shortForm); } /** + * Reads a foreach variable statement * ```ebnf - * foreach_variable = ('&'? variable) | (T_LIST '(' assignment_list ')') + * foreach_variable = variable | + * T_LIST '(' assignment_list ')' | + * '[' array_pair_list ']' * ``` + * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L544 + * @return {Expression} */ ,read_foreach_variable: function() { - if (this.token === '&') { - return this.next().read_variable(false, false, true); - } else if (this.token === this.tok.T_LIST) { + if (this.token === this.tok.T_LIST) { var result = this.node('list'); - this.next().expect('(').next(); + if (this.next().expect('(')) this.next(); var assignList = this.read_assignment_list(); - this.expect(')').next(); - return result(assignList, false); + if (this.expect(')')) this.next(); + return result(assignList); + } else if (this.token === '[') { + return this.read_array(); } else { return this.read_variable(false, false, false); } } }; -},{}],57:[function(require,module,exports){ +},{}],82:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -4697,7 +5519,7 @@ module.exports = { } }; -},{}],58:[function(require,module,exports){ +},{}],83:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -4714,7 +5536,7 @@ module.exports = { * ``` */ read_namespace: function() { - this.expect(this.tok.T_NAMESPACE).next(); + if (this.expect(this.tok.T_NAMESPACE)) this.next(); var result = this.node('namespace'); if (this.token == '{') { this.currentNamespace = ['']; @@ -4756,10 +5578,13 @@ module.exports = { * ``` */ ,read_namespace_name: function() { + var result = this.node('identifier'); if (this.token === this.tok.T_NAMESPACE) { - this.next().expect(this.tok.T_NS_SEPARATOR).next(); + if (this.next().expect(this.tok.T_NS_SEPARATOR)) this.next(); } - return this.read_list(this.tok.T_STRING, this.tok.T_NS_SEPARATOR, true); + return result( + this.read_list(this.tok.T_STRING, this.tok.T_NS_SEPARATOR, true) + ); } /** * ```ebnf @@ -4771,14 +5596,15 @@ module.exports = { ,read_use_statements: function() { var result = []; while(this.token !== this.EOF) { - this.expect(this.tok.T_USE).next(); - this.read_list(this.read_use_statement_mixed, ',').forEach(function(item) { - if (Array.isArray(item)) { - result = result.concat(item); - } else { - result.push(item); - } - }); + if (this.expect(this.tok.T_USE)) { + this.next().read_list(this.read_use_statement_mixed, ',').forEach(function(item) { + if (Array.isArray(item)) { + result = result.concat(item); + } else { + result.push(item); + } + }); + } if(this.token !== this.tok.T_USE) break; } return result; @@ -4823,12 +5649,13 @@ module.exports = { var result = this.node('use'); var use = this.read_use_statement(); if(this.token === this.tok.T_AS) { - this.next().expect(this.tok.T_STRING); - use[1] = this.text(); - this.next(); + if (this.next().expect(this.tok.T_STRING)) { + use[1] = this.text(); + this.next(); + } } else if (this.token === '{') { use = this.next().read_inline_use_declaration(use); - this.expect('}').next(); + if (this.expect('}')) this.next(); return use; } return result.apply(this, use); @@ -4853,7 +5680,7 @@ module.exports = { } }; -},{}],59:[function(require,module,exports){ +},{}],84:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -4943,9 +5770,7 @@ module.exports = { var result = this.node('number'); var value = this.text(); if (this.token === '-') { - this.next().expect([ - this.tok.T_LNUMBER, this.tok.T_DNUMBER - ]); + this.next().expect([this.tok.T_LNUMBER, this.tok.T_DNUMBER]); value += this.text(); } result = result(value); @@ -4960,14 +5785,15 @@ module.exports = { var result = ['constant', value]; if ( this.token == this.tok.T_DOUBLE_COLON) { // class constant MyClass::CONSTANT - this.next().expect([this.tok.T_STRING, this.tok.T_CLASS]); - result[1] = [value, this.text()]; - this.next(); + if (this.next().expect([this.tok.T_STRING, this.tok.T_CLASS])) { + result[1] = [value, this.text()]; + this.next(); + } } // CONSTANT ARRAYS OFFSET : MYCONST[1][0]... while(this.token === '[') { result = ['offset', result, this.next().read_expr()]; - this.expect(']').next(); + if (this.expect(']')) this.next(); } return result; @@ -4990,7 +5816,7 @@ module.exports = { var result; if (this.token === '[') { result = ['offset', expr, this.next().read_expr()]; - this.expect(']').next(); + if (this.expect(']')) this.next(); } else if (this.token === this.tok.T_DOLLAR_OPEN_CURLY_BRACES) { result = ['offset', expr, this.read_encapsed_string_item()]; } @@ -5016,18 +5842,18 @@ module.exports = { result = ['var', this.text()]; if (this.next().token === '[') { result = ['offset', result, this.next().read_expr()]; - this.expect(']').next(); + if (this.expect(']')) this.next(); } } else { result = this.read_expr(); } - this.expect('}').next(); + if (this.expect('}')) this.next(); } else if (this.token === this.tok.T_CURLY_OPEN) { result = this.next().read_variable(false, false, false); - this.expect('}').next(); + if (this.expect('}')) this.next(); } else if (this.token === '[') { result = ['offset', result, this.next().read_expr()]; - this.expect(']').next(); + if (this.expect(']')) this.next(); } else if (this.token === this.tok.T_VARIABLE) { result = this.read_variable(false, true, false); } else { @@ -5036,7 +5862,7 @@ module.exports = { this.tok.T_CURLY_OPEN, this.tok.T_DOLLAR_OPEN_CURLY_BRACES, this.tok.T_ENCAPSED_AND_WHITESPACE - ]) + ]); } return result; } @@ -5063,7 +5889,7 @@ module.exports = { 'bin', '.', result[3], this.read_encapsed_string_item() ]; } - this.expect(expect).next(); + if (this.expect(expect)) this.next(); return result; } /** @@ -5077,7 +5903,7 @@ module.exports = { } }; -},{}],60:[function(require,module,exports){ +},{}],85:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -5117,30 +5943,27 @@ module.exports = { ,read_top_statement: function() { switch(this.token) { case this.tok.T_FUNCTION: - return this.read_function(); + return this.read_function(false, false); // optional flags case this.tok.T_ABSTRACT: case this.tok.T_FINAL: var flag = this.read_class_scope(); - switch(this.token) { - case this.tok.T_CLASS: - return this.read_class(flag); - case this.tok.T_INTERFACE: - return this.read_interface(flag); - default: - var err = this.error([this.tok.T_CLASS, this.tok.T_INTERFACE]); - this.next(); - return err; + if (this.token === this.tok.T_CLASS) { + return this.read_class(flag); + } else { + this.error(this.tok.T_CLASS); + this.next(); + return null; } case this.tok.T_CLASS: - return this.read_class(0); + return this.read_class([0, 0, 0]); case this.tok.T_INTERFACE: - return this.read_interface(0); + return this.read_interface(); case this.tok.T_TRAIT: return this.read_trait(); case this.tok.T_USE: var expr = this.read_use_statements(); - this.expect(';').nextWithComments(); + if (this.expect(';')) this.nextWithComments(); return expr; case this.tok.T_CONST: return this.next().read_const_list(); @@ -5148,7 +5971,9 @@ module.exports = { return this.read_namespace(); case this.tok.T_HALT_COMPILER: var result = this.node('halt'); - this.next().expect('(').next().expect(')').next().expect(';'); + if (this.next().expect('(')) this.next(); + if (this.expect(')')) this.next(); + this.expect(';'); this.lexer.done = true; return result(this.lexer._input.substring( this.lexer.offset @@ -5188,8 +6013,12 @@ module.exports = { this.expect(this.tok.T_STRING); var result = this.node('constant'); var name = this.text(); - this.next().expect('=').next(); - return result(name, this.read_expr()); + if (this.next().expect('=')) { + return result(name, this.next().read_expr()); + } else { + // fallback + return result(name, null); + } }, ',', false); this.expectEndOfStatement(); return result; @@ -5204,8 +6033,11 @@ module.exports = { return this.read_list(function() { this.expect(this.tok.T_STRING); var name = this.text(); - this.next().expect('=').next(); - return [name, this.read_expr()]; + if (this.next().expect('=')) { + return [name, this.next().read_expr()]; + } else { + return [name, null]; + } }, ','); } /** @@ -5217,30 +6049,29 @@ module.exports = { ,read_inner_statement: function() { switch(this.token) { case this.tok.T_FUNCTION: - return this.read_function(); + return this.read_function(false, false); // optional flags case this.tok.T_ABSTRACT: case this.tok.T_FINAL: var flag = this.read_class_scope(); - switch(this.token) { - case this.tok.T_CLASS: - return this.read_class(flag); - case this.tok.T_INTERFACE: - return this.read_interface(flag); - default: - var err = this.error([this.tok.T_CLASS, this.tok.T_INTERFACE]); - // graceful mode : ignore token & go next - this.next(); - return err; + if (this.token === this.tok.T_CLASS) { + return this.read_class(flag); + } else { + this.error(this.tok.T_CLASS); + // graceful mode : ignore token & go next + this.next(); + return null; } case this.tok.T_CLASS: - return this.read_class(0); + return this.read_class([0, 0, 0]); case this.tok.T_INTERFACE: - return this.read_interface(0); + return this.read_interface(); case this.tok.T_TRAIT: return this.read_trait(); case this.tok.T_HALT_COMPILER: - this.next().expect('(').next().expect(')').next().expect(';').next(); + if (this.next().expect('(')) this.next(); + if (this.expect(')')) this.next(); + if (this.expect(';')) this.next(); this.raiseError('__HALT_COMPILER() can only be used from the outermost scope'); default: return this.read_statement(); @@ -5272,20 +6103,22 @@ module.exports = { case this.tok.T_DOC_COMMENT: return this.read_doc_comment(); case this.tok.T_RETURN: - case this.tok.T_BREAK: - case this.tok.T_CONTINUE: - var mode; - switch(this.token) { - case this.tok.T_RETURN: mode = 'return'; break; - case this.tok.T_BREAK: mode = 'break'; break; - case this.tok.T_CONTINUE: mode = 'continue'; break; - } - var expr = null; + var result = this.node('return'), expr = null; if (!this.next().is('EOS')) { expr = this.read_expr(); } this.expectEndOfStatement(); - return [mode, expr]; + return result(expr); + + case this.tok.T_BREAK: + var result = this.node('break'); + this.next().expectEndOfStatement(); + return result(); + + case this.tok.T_CONTINUE: + var result = this.node('continue'); + this.next().expectEndOfStatement(); + return result(); case this.tok.T_GLOBAL: var items = this.next().read_list(this.read_simple_variable, ','); @@ -5299,13 +6132,16 @@ module.exports = { // static keyword for a class this.lexer.tokens.push(current); var expr = this.next().read_expr(); - this.expect(';').nextWithComments(); + this.expect(';') && this.nextWithComments(); return expr; } var items = this.read_list(function() { - var name = this.expect(this.tok.T_VARIABLE).text(); - var value = null; - if (this.next().token === '=') { + var value = null, name = null; + if (this.expect(this.tok.T_VARIABLE)) { + name = this.text(); + this.next(); + } + if (this.token === '=') { value = this.next().read_expr(); } return [name, value]; @@ -5319,7 +6155,7 @@ module.exports = { withParanthesis && this.next(); var args = this.read_list(this.read_expr, ','); if (withParanthesis) { - this.expect(')').next(); + this.expect(')') && this.next(); } this.expectEndOfStatement(); return result(args); @@ -5331,28 +6167,25 @@ module.exports = { case this.tok.T_UNSET: var result = this.node('unset'); - this.next().expect('(').next(); + this.next().expect('(') && this.next(); var items = this.read_list(this.read_variable, ','); - if (this.expect(')').next().expect(';')) { - result = result(items); - this.nextWithComments(); - } else { - result = result(items); - } - return result; + this.expect(')') && this.next(); + this.expect(';') && this.nextWithComments(); + return result(items); case this.tok.T_DECLARE: var result = this.node('declare'), options, body; - this.next().expect('(').next(); + this.next().expect('(') && this.next(); options = this.read_declare_list(); - this.expect(')').nextWithComments(); + this.expect(')') && this.nextWithComments(); if (this.token === ':') { body = []; this.next(); while(this.token != this.EOF && this.token !== this.tok.T_ENDDECLARE) { body.push(this.read_statement()); } - this.ignoreComments().expect(this.tok.T_ENDDECLARE).next().expectEndOfStatement(); + this.ignoreComments().expect(this.tok.T_ENDDECLARE) && this.next(); + this.expectEndOfStatement(); } else { body = this.read_statement(); } @@ -5384,14 +6217,16 @@ module.exports = { // default fallback expr this.lexer.tokens.push(current); var expr = this.next().read_expr(); - this.expect([';', this.tok.T_CLOSE_TAG]).nextWithComments(); + this.expect([';', this.tok.T_CLOSE_TAG]) && this.nextWithComments(); return expr; } case this.tok.T_GOTO: - var result = this.node('goto'); - var label = this.next().expect(this.tok.T_STRING).text(); - this.next().expectEndOfStatement(); + var result = this.node('goto'), label = null; + if (this.next().expect(this.tok.T_STRING)) { + label = this.text(); + this.next().expectEndOfStatement(); + } return result(label); default: // default fallback expr @@ -5406,46 +6241,55 @@ module.exports = { * ``` */ ,read_code_block: function(top) { - this.expect('{').nextWithComments(); + var result = this.node('block'); + this.expect('{') && this.nextWithComments(); var body = top ? this.read_top_statements() : this.read_inner_statements() ; - this.expect('}').nextWithComments(); - return body; + this.expect('}') && this.nextWithComments(); + return result(null, body); } }; -},{}],61:[function(require,module,exports){ +},{}],86:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors * @url http://glayzzle.com */ +"use strict"; + module.exports = { /** * Reads a switch statement * ```ebnf * switch ::= T_SWITCH '(' expr ')' switch_case_list * ``` + * @return {Switch} + * @see http://php.net/manual/en/control-structures.switch.php */ read_switch: function() { - this.expect(this.tok.T_SWITCH).next(); - var result = this.node('switch'); - this.expect('(').next(); - var expr = this.read_expr(); - this.expect(')').next(); - var cases = this.read_switch_case_list(); - return result(expr, cases); + this.expect(this.tok.T_SWITCH) && this.next(); + var result = this.node('switch'), test, body, shortForm; + this.expect('(') && this.next(); + test = this.read_expr(); + this.expect(')') && this.next(); + shortForm = (this.token === ':'); + body = this.read_switch_case_list(); + return result(test, body, shortForm); } /** * ```ebnf * switch_case_list ::= '{' ';'? case_list* '}' | ':' ';'? case_list* T_ENDSWITCH ';' * ``` + * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L566 */ ,read_switch_case_list: function() { // DETECT SWITCH MODE - var expect = null, result = []; + var expect = null, + result = this.node('block'), + items = []; if (this.token === '{') { expect = '}'; } else if (this.token === ':') { @@ -5454,9 +6298,8 @@ module.exports = { this.expect(['{', ':']); } // OPTIONNAL ';' - this.next(); - if (this.token === ';') { - // why ? it's compliant with spec but why ... wtf ? + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L570 + if (this.next().token === ';') { this.next(); } // IGNORE THE CLOSE TAG TOKEN WITH SHORT MODE @@ -5465,14 +6308,14 @@ module.exports = { } // EXTRACTING CASES while(this.token !== this.EOF && this.token !== expect) { - result.push( this.read_case_list(expect) ); + items.push( this.read_case_list(expect) ); } // CHECK END TOKEN - this.expect(expect).next(); + this.expect(expect) && this.next(); if (expect === this.tok.T_ENDSWITCH) { this.expectEndOfStatement(); } - return result; + return result(null, items); } /** * ```ebnf @@ -5480,32 +6323,32 @@ module.exports = { * ``` */ ,read_case_list: function(stopToken) { - var result = { - condition: false, - body: [] - }; + var result = this.node('case'), test = null, body = null, items = []; if (this.token === this.tok.T_CASE) { - result.condition = this.next().read_expr(); + test = this.next().read_expr(); } else if (this.token === this.tok.T_DEFAULT) { // the defaut entry - no condition this.next(); } else { this.expect([this.tok.T_CASE, this.tok.T_DEFAULT]); } - this.expect([':', ';']).next(); + this.expect([':', ';']) && this.next(); + body = this.node('block'); while( this.token != this.EOF && this.token !== stopToken && this.token !== this.tok.T_CASE && this.token !== this.tok.T_DEFAULT ) { - result.body.push(this.read_inner_statement()); + items.push(this.read_inner_statement()); } - return result; + return result( + test, items.length > 0 ? body(null, items) : null + ); } }; -},{}],62:[function(require,module,exports){ +},{}],87:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -5532,10 +6375,10 @@ module.exports = { this.ignoreComments(); while(this.token === this.tok.T_CATCH) { - this.next().expect('(').next(); + this.next().expect('(') && this.next(); var exName = this.read_namespace_name(); var varName = this.read_variable(true, false, false); - this.expect(')').nextWithComments(); + this.expect(')') && this.nextWithComments(); catches.push({ exception: exName, as: varName, @@ -5550,7 +6393,91 @@ module.exports = { } }; -},{}],63:[function(require,module,exports){ +},{}],88:[function(require,module,exports){ +/*! + * Defines a list of helper functions for parsing + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +module.exports = { + /** + * Reads a short form of tokens + * @param {Number} token - The ending token + * @return {Block} + */ + read_short_form: function(token) { + var body = this.node('block'), items = []; + if (this.expect(':')) this.next(); + while(this.token != this.EOF && this.token !== token) { + items.push(this.read_inner_statement()); + } + if (this.expect(token)) this.next(); + this.expectEndOfStatement(); + return body(null, items); + } + + /** + * Helper : reads a list of tokens / sample : T_STRING ',' T_STRING ... + * ```ebnf + * list ::= separator? ( item separator )* item + * ``` + */ + ,read_list: function(item, separator, preserveFirstSeparator) { + var result = []; + + if (this.token == separator) { + if (preserveFirstSeparator) result.push(''); + this.next(); + } + + if (typeof (item) === "function") { + do { + result.push(item.apply(this, [])); + if (this.token != separator) { + break; + } + } while(this.next().token != this.EOF); + } else { + if (this.expect(item)) { + result.push(this.text()); + } + while (this.next().token != this.EOF) { + if (this.token != separator) break; + // trim current separator & check item + if (this.next().token != item) break; + result.push(this.text()); + } + } + return result; + } + + /** + * Reads a list of names separated by a comma + * + * ```ebnf + * name_list ::= namespace (',' namespace)* + * ``` + * + * Sample code : + * ```php + * var_{$prop} what = ['bin', '.', what, this.next().read_expr()]; - this.expect('}').next(); + this.expect('}') && this.next(); } break; case this.tok.T_VARIABLE: @@ -5693,7 +6622,7 @@ module.exports = { if (this.token === '{') { // $obj->${$varname} what = this.next().read_expr(); - this.expect('}').next(); + this.expect('}') && this.next(); } else { // $obj->$$varname what = this.read_expr(); @@ -5701,7 +6630,7 @@ module.exports = { break; case '{': what = this.next().read_expr(); - this.expect('}').next(); + this.expect('}') && this.next(); break; default: what = this.error([this.tok.T_STRING, this.tok.T_VARIABLE]); @@ -5764,10 +6693,10 @@ module.exports = { var offset = this.next().token === ']' ? null : this.read_dim_offset(); result = ['offset', result, offset]; } - this.expect(']').next(); + this.expect(']') && this.next(); } else if (this.token == '{' && !encapsed) { result = ['offset', result, this.next().read_expr()]; - this.expect('}').next(); + this.expect('}') && this.next(); } else break; } return result; @@ -5779,16 +6708,17 @@ module.exports = { */ ,read_simple_variable: function(byref) { var result = this.node('variable'); - if (this.expect([this.tok.T_VARIABLE, '$']).token === this.tok.T_VARIABLE) { + if (this.expect([this.tok.T_VARIABLE, '$']) && this.token === this.tok.T_VARIABLE) { // plain variable name result = result(this.text(), byref); this.next(); } else { + if (this.token === '$') this.next(); // dynamic variable name - switch(this.next().token) { + switch(this.token) { case '{': result = this.next().read_expr(); - this.expect('}').next(); + this.expect('}') && this.next(); break; case '$': // $$$var result = ['lookup', 'var', this.read_simple_variable(false)]; @@ -5808,7 +6738,7 @@ module.exports = { } }; -},{}],64:[function(require,module,exports){ +},{}],90:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -6223,4 +7153,4 @@ engine.prototype.tokenGetAll = function(buffer) { // exports the function module.exports = engine; -},{"./ast":2,"./lexer":40,"./parser":49,"./tokens":64}]},{},[]); +},{"./ast":2,"./lexer":65,"./parser":74,"./tokens":90}]},{},[]); diff --git a/dist/php-parser.min.js b/dist/php-parser.min.js index 88e321660..a774f654e 100644 --- a/dist/php-parser.min.js +++ b/dist/php-parser.min.js @@ -1,78 +1,84 @@ require=function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g1)for(var c=1;c=this.size,!this.all_tokens&&this.mode_eval?this.begin("ST_IN_SCRIPTING"):this.begin("INITIAL"),this},d.prototype.input=function(a){ -var b=this._input[this.offset];return b?(this.yytext+=b,this.offset++,"\r"===b&&"\n"===this._input[this.offset]&&(this.yytext+="\n",this.offset++),"\n"===b||"\r"===b?(this.yylloc.last_line=++this.yylineno,this.yyprevcol=this.yylloc.last_column,this.yylloc.last_column=0):this.yylloc.last_column++,b):""},d.prototype.unput=function(a){if(1===a)this.offset--,"\n"===this._input[this.offset]&&"\r"===this._input[this.offset-1]&&(this.offset--,a++),"\r"!==this._input[this.offset]&&"\n"!==this._input[this.offset]||(this.yylloc.last_line--,this.yylineno--,this.yylloc.last_column=this.yyprevcol),this.yytext=this.yytext.substring(0,this.yytext.length-a);else if(a>0)if(this.offset-=a,a0?this.conditionStack.pop():this.conditionStack[0];if(this.curCondition=this.conditionStack[this.conditionStack.length-1],this.stateCb=this["match"+this.curCondition],"function"!=typeof this.stateCb)throw new Error('Undefined condition state "'+this.curCondition+'"');return b},d.prototype.next=function(){var a;return this._input||(this.done=!0),this.done?this.EOF:(this.yylloc.first_offset=this.offset,this.yylloc.first_line=this.yylloc.last_line,this.yylloc.first_column=this.yylloc.last_column,this.yytext="",this.tokens.length>0?(a=this.tokens.shift(),"object"==typeof a[1]?this.setState(a[1]):this.consume(a[1]),a=a[0]):a=this.stateCb.apply(this,[]),this.offset>=this.size&&0===this.tokens.length&&(this.done=!0),a)},[a("./lexer/comments.js"),a("./lexer/initial.js"),a("./lexer/numbers.js"),a("./lexer/property.js"),a("./lexer/scripting.js"),a("./lexer/strings.js"),a("./lexer/tokens.js"),a("./lexer/utils.js")].forEach(function(a){for(var b in a)d.prototype[b]=a[b]; -}),b.exports=d},{"./lexer/comments.js":41,"./lexer/initial.js":42,"./lexer/numbers.js":43,"./lexer/property.js":44,"./lexer/scripting.js":45,"./lexer/strings.js":46,"./lexer/tokens.js":47,"./lexer/utils.js":48}],41:[function(a,b,c){b.exports={T_COMMENT:function(){for(;this.offset"===this._input[this.offset])return this.unput(1),this.tok.T_COMMENT;if("%"===a&&this.aspTagMode&&">"===this._input[this.offset])return this.unput(1),tthis.tok.T_COMMENT}return this.tok.T_COMMENT},T_DOC_COMMENT:function(){var a=this.input(),b=this.tok.T_COMMENT;if("*"===a){if(a=this.input(),this.is_WHITESPACE()&&(b=this.tok.T_DOC_COMMENT),"/"===a)return b;this.unput(1)}for(;this.offset1&&"INITIAL"===this.conditionStack[this.conditionStack.length-1]?this.popState():this.begin("ST_IN_SCRIPTING"), -this},matchINITIAL:function(){for(;this.offset0&&this.tok.T_INLINE_HTML}}},{}],43:[function(a,b,c){(function(a){if("x64"==a.arch)var c=20,d="9223372036854775808";else var c=11,d="2147483648";b.exports={consume_NUM:function(){var a=this.yytext[0],b="."===this.yytext[0];if("0"===a)if(a=this.input(),"x"===a||"X"===a){if(this.input(), -this.is_HEX())return this.consume_HNUM();this.unput(2)}else if("b"===a||"B"===a){if(a=this.input(),"0"===a||"1"===a)return this.consume_BNUM();this.unput(2)}else this.is_NUM()||this.unput(1);for(;this.offset"===a)return this.tok.T_OBJECT_OPERATOR;this.unput(1)}else if(this.is_LABEL_START())return this.consume_LABEL(),this.tok.T_STRING;return this.popState(),this.unput(1),!1},matchST_LOOKING_FOR_VARNAME:function(){var a=this.input();return this.is_LABEL_START()?(this.consume_LABEL(),a=this.input(),this.popState(),"["===a||"}"===a?(this.begin("ST_IN_SCRIPTING"),this.unput(1),this.tok.T_STRING_VARNAME):(this.unput(this.yytext.length),!1)):(this.unput(1),this.popState(),this.begin("ST_IN_SCRIPTING"),!1)},matchST_VAR_OFFSET:function(){var a=this.input();if(this.is_NUM())return this.consume_NUM(),this.tok.T_NUM_STRING;if("]"===a)return this.popState(),"]";if("$"===a){if(this.input(),this.is_LABEL_START())return this.consume_LABEL(),this.tok.T_VARIABLE;throw new Error("Unexpected terminal")}if(this.is_LABEL_START())return this.consume_LABEL(), -this.tok.T_STRING;if(this.is_WHITESPACE()||"\\"===a||"'"===a||"#"===a)return this.tok.T_ENCAPSED_AND_WHITESPACE;if("["===a||"{"===a||"}"===a||'"'===a||"`"===a||this.is_TOKEN())return a;throw new Error("Unexpected terminal")}}},{}],45:[function(a,b,c){b.exports={matchST_IN_SCRIPTING:function(){var a=this.input();switch(a){case" ":case"\t":case"\n":case"\r":case"\r\n":return this.T_WHITESPACE();case"#":return this.T_COMMENT();case"/":return"/"===this._input[this.offset]?this.T_COMMENT():"*"===this._input[this.offset]?(this.input(),this.T_DOC_COMMENT()):this.consume_TOKEN();case"'":return this.T_CONSTANT_ENCAPSED_STRING();case'"':return this.ST_DOUBLE_QUOTES();case"`":return this.begin("ST_BACKQUOTE"),"`";case"?":if(!this.aspTagMode&&this.tryMatch(">")){this.input();var b=this._input[this.offset];return"\n"!==b&&"\r"!==b||this.input(),this.conditionStack.length>1&&this.begin("INITIAL"),this.tok.T_CLOSE_TAG}return this.consume_TOKEN();case"%":return this.aspTagMode&&">"===this._input[this.offset]?(this.input(),a=this._input[this.offset], -"\n"!==a&&"\r"!==a||this.input(),this.aspTagMode=!1,this.conditionStack.length>1&&this.begin("INITIAL"),this.tok.T_CLOSE_TAG):this.consume_TOKEN();case"{":return this.begin("ST_IN_SCRIPTING"),"{";case"}":return this.conditionStack.length>2&&this.popState(),"}";default:if("."===a){if(this.input(),this.is_NUM())return this.consume_NUM();this.unput(1)}if(this.is_NUM())return this.consume_NUM();if(this.is_LABEL_START())return this.consume_LABEL().T_STRING();if(this.is_TOKEN())return this.consume_TOKEN()}throw new Error('Bad terminal sequence "'+a+'" at line '+this.yylineno+" (offset "+this.offset+")")},T_WHITESPACE:function(){for(;this.offset=this.size,!this.all_tokens&&this.mode_eval?this.begin("ST_IN_SCRIPTING"):this.begin("INITIAL"),this},d.prototype.input=function(a){var b=this._input[this.offset];return b?(this.yytext+=b,this.offset++,"\r"===b&&"\n"===this._input[this.offset]&&(this.yytext+="\n", +this.offset++),"\n"===b||"\r"===b?(this.yylloc.last_line=++this.yylineno,this.yyprevcol=this.yylloc.last_column,this.yylloc.last_column=0):this.yylloc.last_column++,b):""},d.prototype.unput=function(a){if(1===a)this.offset--,"\n"===this._input[this.offset]&&"\r"===this._input[this.offset-1]&&(this.offset--,a++),"\r"!==this._input[this.offset]&&"\n"!==this._input[this.offset]||(this.yylloc.last_line--,this.yylineno--,this.yylloc.last_column=this.yyprevcol),this.yytext=this.yytext.substring(0,this.yytext.length-a);else if(a>0)if(this.offset-=a,a0?this.conditionStack.pop():this.conditionStack[0]; +if(this.curCondition=this.conditionStack[this.conditionStack.length-1],this.stateCb=this["match"+this.curCondition],"function"!=typeof this.stateCb)throw new Error('Undefined condition state "'+this.curCondition+'"');return b},d.prototype.next=function(){var a;return this._input||(this.done=!0),this.done?this.EOF:(this.yylloc.first_offset=this.offset,this.yylloc.first_line=this.yylloc.last_line,this.yylloc.first_column=this.yylloc.last_column,this.yytext="",this.tokens.length>0?(a=this.tokens.shift(),"object"==typeof a[1]?this.setState(a[1]):this.consume(a[1]),a=a[0]):a=this.stateCb.apply(this,[]),this.offset>=this.size&&0===this.tokens.length&&(this.done=!0),a)},[a("./lexer/comments.js"),a("./lexer/initial.js"),a("./lexer/numbers.js"),a("./lexer/property.js"),a("./lexer/scripting.js"),a("./lexer/strings.js"),a("./lexer/tokens.js"),a("./lexer/utils.js")].forEach(function(a){for(var b in a)d.prototype[b]=a[b]}),b.exports=d},{"./lexer/comments.js":66,"./lexer/initial.js":67,"./lexer/numbers.js":68,"./lexer/property.js":69, +"./lexer/scripting.js":70,"./lexer/strings.js":71,"./lexer/tokens.js":72,"./lexer/utils.js":73}],66:[function(a,b,c){b.exports={T_COMMENT:function(){for(;this.offset"===this._input[this.offset])return this.unput(1),this.tok.T_COMMENT;if("%"===a&&this.aspTagMode&&">"===this._input[this.offset])return this.unput(1),tthis.tok.T_COMMENT}return this.tok.T_COMMENT},T_DOC_COMMENT:function(){var a=this.input(),b=this.tok.T_COMMENT;if("*"===a){if(a=this.input(),this.is_WHITESPACE()&&(b=this.tok.T_DOC_COMMENT),"/"===a)return b;this.unput(1)}for(;this.offset1&&"INITIAL"===this.conditionStack[this.conditionStack.length-1]?this.popState():this.begin("ST_IN_SCRIPTING"),this},matchINITIAL:function(){for(;this.offset0&&this.tok.T_INLINE_HTML}}},{}],68:[function(a,b,c){(function(a){if("x64"==a.arch)var c=20,d="9223372036854775808";else var c=11,d="2147483648";b.exports={consume_NUM:function(){var a=this.yytext[0],b="."===this.yytext[0];if("0"===a)if(a=this.input(),"x"===a||"X"===a){if(this.input(),this.is_HEX())return this.consume_HNUM();this.unput(2); +}else if("b"===a||"B"===a){if(a=this.input(),"0"===a||"1"===a)return this.consume_BNUM();this.unput(2)}else this.is_NUM()||this.unput(1);for(;this.offset"===a)return this.tok.T_OBJECT_OPERATOR;this.unput(1)}else if(this.is_LABEL_START())return this.consume_LABEL(),this.tok.T_STRING;return this.popState(),this.unput(1),!1},matchST_LOOKING_FOR_VARNAME:function(){var a=this.input();return this.is_LABEL_START()?(this.consume_LABEL(),a=this.input(),this.popState(),"["===a||"}"===a?(this.begin("ST_IN_SCRIPTING"),this.unput(1),this.tok.T_STRING_VARNAME):(this.unput(this.yytext.length),!1)):(this.unput(1),this.popState(),this.begin("ST_IN_SCRIPTING"),!1)},matchST_VAR_OFFSET:function(){var a=this.input();if(this.is_NUM())return this.consume_NUM(),this.tok.T_NUM_STRING;if("]"===a)return this.popState(),"]";if("$"===a){if(this.input(),this.is_LABEL_START())return this.consume_LABEL(),this.tok.T_VARIABLE;throw new Error("Unexpected terminal")}if(this.is_LABEL_START())return this.consume_LABEL(),this.tok.T_STRING; +if(this.is_WHITESPACE()||"\\"===a||"'"===a||"#"===a)return this.tok.T_ENCAPSED_AND_WHITESPACE;if("["===a||"{"===a||"}"===a||'"'===a||"`"===a||this.is_TOKEN())return a;throw new Error("Unexpected terminal")}}},{}],70:[function(a,b,c){b.exports={matchST_IN_SCRIPTING:function(){var a=this.input();switch(a){case" ":case"\t":case"\n":case"\r":case"\r\n":return this.T_WHITESPACE();case"#":return this.T_COMMENT();case"/":return"/"===this._input[this.offset]?this.T_COMMENT():"*"===this._input[this.offset]?(this.input(),this.T_DOC_COMMENT()):this.consume_TOKEN();case"'":return this.T_CONSTANT_ENCAPSED_STRING();case'"':return this.ST_DOUBLE_QUOTES();case"`":return this.begin("ST_BACKQUOTE"),"`";case"?":if(!this.aspTagMode&&this.tryMatch(">")){this.input();var b=this._input[this.offset];return"\n"!==b&&"\r"!==b||this.input(),this.conditionStack.length>1&&this.begin("INITIAL"),this.tok.T_CLOSE_TAG}return this.consume_TOKEN();case"%":return this.aspTagMode&&">"===this._input[this.offset]?(this.input(),a=this._input[this.offset], +"\n"!==a&&"\r"!==a||this.input(),this.aspTagMode=!1,this.conditionStack.length>1&&this.begin("INITIAL"),this.tok.T_CLOSE_TAG):this.consume_TOKEN();case"{":return this.begin("ST_IN_SCRIPTING"),"{";case"}":return this.conditionStack.length>2&&this.popState(),"}";default:if("."===a){if(this.input(),this.is_NUM())return this.consume_NUM();this.unput(1)}if(this.is_NUM())return this.consume_NUM();if(this.is_LABEL_START())return this.consume_LABEL().T_STRING();if(this.is_TOKEN())return this.consume_TOKEN()}throw new Error('Bad terminal sequence "'+a+'" at line '+this.yylineno+" (offset "+this.offset+")")},T_WHITESPACE:function(){for(;this.offset2&&this.appendToken(this.tok.T_ENCAPSED_AND_WHITESPACE,this.yytext.length-b),this.unput(this.yytext.length-b),this.begin("ST_DOUBLE_QUOTES"),this.yytext},isDOC_MATCH:function(){if(this._input.substring(this.offset-1,this.offset-1+this.heredoc_label.length)===this.heredoc_label){var a=this._input[this.offset-1+this.heredoc_label.length];if("\n"===a||"\r"===a||";"===a)return!0}return!1},matchST_NOWDOC:function(){if(this.isDOC_MATCH())return this.consume(this.heredoc_label.length),this.popState(),this.tok.T_END_HEREDOC;for(var a=this._input[this.offset-1];this.offset2?(this.appendToken(this.tok.T_DOLLAR_OPEN_CURLY_BRACES,2),this.unput(2),this.tok.T_ENCAPSED_AND_WHITESPACE):this.tok.T_DOLLAR_OPEN_CURLY_BRACES;if(this.is_LABEL_START()){var b=this.offset,c=this.consume_VARIABLE();return this.yytext.length>this.offset-b+2?(this.appendToken(c,this.offset-b+2),this.unput(this.offset-b+2),this.tok.T_ENCAPSED_AND_WHITESPACE):c}}else if("{"===a){if(a=this.input(),"$"===a)return this.begin("ST_IN_SCRIPTING"),this.yytext.length>2?(this.appendToken(this.tok.T_CURLY_OPEN,1),this.unput(2),this.tok.T_ENCAPSED_AND_WHITESPACE):(this.unput(1),this.tok.T_CURLY_OPEN)}else a=this.input();return this.tok.T_ENCAPSED_AND_WHITESPACE},consume_VARIABLE:function(){if(this.consume_LABEL(), ch=this.input(),"["==ch)return this.unput(1),this.begin("ST_VAR_OFFSET"),this.tok.T_VARIABLE;if("-"===ch){if(">"===this.input())return this.input(),this.is_LABEL_START()&&this.begin("ST_LOOKING_FOR_PROPERTY"),this.unput(3),this.tok.T_VARIABLE;this.unput(2)}else this.unput(1);return this.tok.T_VARIABLE},matchST_BACKQUOTE:function(){var a=this.input();if("$"===a){if(a=this.input(),"{"===a)return this.begin("ST_LOOKING_FOR_VARNAME"),this.tok.T_DOLLAR_OPEN_CURLY_BRACES;if(this.is_LABEL_START()){var b=this.consume_VARIABLE();return b}}else if("{"===a){if("$"===this._input[this.offset])return this.begin("ST_IN_SCRIPTING"),this.tok.T_CURLY_OPEN}else if('"'===a)return this.popState(),'"';for(;this.offset2?(this.appendToken(this.tok.T_DOLLAR_OPEN_CURLY_BRACES,2),this.unput(2),this.tok.T_ENCAPSED_AND_WHITESPACE):this.tok.T_DOLLAR_OPEN_CURLY_BRACES; if(this.is_LABEL_START()){var c=this.offset,d=this.consume_VARIABLE();return this.yytext.length>this.offset-c+2?(this.appendToken(d,this.offset-c+2),this.unput(this.offset-c+2),this.tok.T_ENCAPSED_AND_WHITESPACE):d}this.unput(1)}else if("{"===a){if(a=this.input(),"$"===a)return this.begin("ST_IN_SCRIPTING"),this.yytext.length>2?(this.appendToken(this.tok.T_CURLY_OPEN,1),this.unput(2),this.tok.T_ENCAPSED_AND_WHITESPACE):(this.unput(1),this.tok.T_CURLY_OPEN);this.unput(1)}}a=this.input()}return this.tok.T_ENCAPSED_AND_WHITESPACE},matchST_DOUBLE_QUOTES:function(){var a=this.input();if("$"===a){if(a=this.input(),"{"===a)return this.begin("ST_LOOKING_FOR_VARNAME"),this.tok.T_DOLLAR_OPEN_CURLY_BRACES;if(this.is_LABEL_START()){var b=this.consume_VARIABLE();return b}}else if("{"===a){if("$"===this._input[this.offset])return this.begin("ST_IN_SCRIPTING"),this.tok.T_CURLY_OPEN}else if('"'===a)return this.popState(),'"';for(;this.offset2?(this.appendToken(this.tok.T_DOLLAR_OPEN_CURLY_BRACES,2),this.unput(2),this.tok.T_ENCAPSED_AND_WHITESPACE):this.tok.T_DOLLAR_OPEN_CURLY_BRACES;if(this.is_LABEL_START()){var c=this.offset,d=this.consume_VARIABLE();return this.yytext.length>this.offset-c+2?(this.appendToken(d,this.offset-c+2),this.unput(this.offset-c+2),this.tok.T_ENCAPSED_AND_WHITESPACE):d}this.unput(1)}else if("{"===a){if(a=this.input(),"$"===a)return this.begin("ST_IN_SCRIPTING"),this.yytext.length>2?(this.appendToken(this.tok.T_CURLY_OPEN,1),this.unput(2),this.tok.T_ENCAPSED_AND_WHITESPACE):(this.unput(1),this.tok.T_CURLY_OPEN);this.unput(1)}}a=this.input()}return this.tok.T_ENCAPSED_AND_WHITESPACE}}},{}],47:[function(a,b,c){b.exports={T_STRING:function(){var a=this.yytext.toLowerCase(),b=this.keywords[a];if(!b)if("yield"===a)this.tryMatch(" from")?(this.consume(5),b=this.tok.T_YIELD_FROM):b=this.tok.T_YIELD;else if(b=this.tok.T_STRING, +break}if("$"===a){if(a=this.input(),"{"===a)return this.begin("ST_LOOKING_FOR_VARNAME"),this.yytext.length>2?(this.appendToken(this.tok.T_DOLLAR_OPEN_CURLY_BRACES,2),this.unput(2),this.tok.T_ENCAPSED_AND_WHITESPACE):this.tok.T_DOLLAR_OPEN_CURLY_BRACES;if(this.is_LABEL_START()){var c=this.offset,d=this.consume_VARIABLE();return this.yytext.length>this.offset-c+2?(this.appendToken(d,this.offset-c+2),this.unput(this.offset-c+2),this.tok.T_ENCAPSED_AND_WHITESPACE):d}this.unput(1)}else if("{"===a){if(a=this.input(),"$"===a)return this.begin("ST_IN_SCRIPTING"),this.yytext.length>2?(this.appendToken(this.tok.T_CURLY_OPEN,1),this.unput(2),this.tok.T_ENCAPSED_AND_WHITESPACE):(this.unput(1),this.tok.T_CURLY_OPEN);this.unput(1)}}a=this.input()}return this.tok.T_ENCAPSED_AND_WHITESPACE}}},{}],72:[function(a,b,c){b.exports={T_STRING:function(){var a=this.yytext.toLowerCase(),b=this.keywords[a];if(!b)if("yield"===a)this.tryMatch(" from")?(this.consume(5),b=this.tok.T_YIELD_FROM):b=this.tok.T_YIELD;else if(b=this.tok.T_STRING, "b"===a||"B"===a){var c=this.input(1);if('"'===c)return this.ST_DOUBLE_QUOTES();if("'"===c)return this.T_CONSTANT_ENCAPSED_STRING();this.unput(1)}return b},consume_TOKEN:function(){var a=this._input[this.offset-1],b=this.tokenTerminals[a];return b?b.apply(this,[]):this.yytext},tokenTerminals:{$:function(){return this.offset++,this.is_LABEL_START()?(this.offset--,this.consume_LABEL(),this.tok.T_VARIABLE):(this.offset--,"$")},"-":function(){var a=this._input[this.offset];return">"===a?(this.begin("ST_LOOKING_FOR_PROPERTY").input(),this.tok.T_OBJECT_OPERATOR):"-"===a?(this.input(),this.tok.T_DEC):"="===a?(this.input(),this.tok.T_MINUS_EQUAL):"-"},"\\":function(){return this.tok.T_NS_SEPARATOR},"/":function(){return"="===this._input[this.offset]?(this.input(),this.tok.T_DIV_EQUAL):"/"},":":function(){return":"===this._input[this.offset]?(this.input(),this.tok.T_DOUBLE_COLON):":"},"(":function(){var a=this.offset;if(this.input(),this.is_TABSPACE()&&this.consume_TABSPACE().input(),this.is_LABEL_START()){var b=this.yytext.length; this.consume_LABEL();var c=this.yytext.substring(b-1).toLowerCase(),d=this.castKeywords[c];if(d&&(this.input(),this.is_TABSPACE()&&this.consume_TABSPACE().input(),")"===this._input[this.offset-1]))return d}return this.unput(this.offset-a),"("},"=":function(){var a=this._input[this.offset];return">"===a?(this.input(),this.tok.T_DOUBLE_ARROW):"="===a?"="===this._input[this.offset+1]?(this.consume(2),this.tok.T_IS_IDENTICAL):(this.input(),this.tok.T_IS_EQUAL):"="},"+":function(){var a=this._input[this.offset];return"+"===a?(this.input(),this.tok.T_INC):"="===a?(this.input(),this.tok.T_PLUS_EQUAL):"+"},"!":function(){return"="===this._input[this.offset]?"="===this._input[this.offset+1]?(this.consume(2),this.tok.T_IS_NOT_IDENTICAL):(this.input(),this.tok.T_IS_NOT_EQUAL):"!"},"?":function(){return"?"===this._input[this.offset]?(this.input(),this.tok.T_COALESCE):"?"},"<":function(){var a=this._input[this.offset];return"<"===a?(a=this._input[this.offset+1],"="===a?(this.consume(2),this.tok.T_SL_EQUAL):"<"===a&&this.is_HEREDOC()?this.tok.T_START_HEREDOC:(this.input(), this.tok.T_SL)):"="===a?(this.input(),">"===this._input[this.offset]?(this.input(),this.tok.T_SPACESHIP):this.tok.T_IS_SMALLER_OR_EQUAL):">"===a?(this.input(),this.tok.T_IS_NOT_EQUAL):"<"},">":function(){var a=this._input[this.offset];return"="===a?(this.input(),this.tok.T_IS_GREATER_OR_EQUAL):">"===a?(a=this._input[this.offset+1],"="===a?(this.consume(2),this.tok.T_SR_EQUAL):(this.input(),this.tok.T_SR)):">"},"*":function(){var a=this._input[this.offset];return"="===a?(this.input(),this.tok.T_MUL_EQUAL):"*"===a?(this.input(),"="===this._input[this.offset]?(this.input(),this.tok.T_POW_EQUAL):this.tok.T_POW):"*"},".":function(){var a=this._input[this.offset];return"="===a?(this.input(),this.tok.T_CONCAT_EQUAL):"."===a&&"."===this._input[this.offset+1]?(this.consume(2),this.tok.T_ELLIPSIS):"."},"%":function(){return"="===this._input[this.offset]?(this.input(),this.tok.T_MOD_EQUAL):"%"},"&":function(){var a=this._input[this.offset];return"="===a?(this.input(),this.tok.T_AND_EQUAL):"&"===a?(this.input(),this.tok.T_BOOLEAN_AND):"&"; -},"|":function(){var a=this._input[this.offset];return"="===a?(this.input(),this.tok.T_OR_EQUAL):"|"===a?(this.input(),this.tok.T_BOOLEAN_OR):"|"},"^":function(){return"="===this._input[this.offset]?(this.input(),this.tok.T_XOR_EQUAL):"^"}}}},{}],48:[function(a,b,c){var d=";:,.\\[]()|^&+-/*=%!~$<>?@";b.exports={is_NUM:function(){var a=this._input.charCodeAt(this.offset-1);return a>47&&a<58},is_LABEL:function(){var a=this._input.charCodeAt(this.offset-1);return a>96&&a<123||a>64&&a<91||95===a||a>47&&a<58||a>126},is_LABEL_START:function(){var a=this._input.charCodeAt(this.offset-1);return a>96&&a<123||a>64&&a<91||95===a||a>126},consume_LABEL:function(){for(;this.offset47&&a<58||a>64&&a<71||a>96&&a<103}}},{}],49:[function(a,b,c){function d(a){return"."!=a&&","!=a&&!isNaN(parseFloat(a))&&isFinite(a)}var e=function(a,b){this.lexer=a,this.ast=b,this.tok=a.tok,this.EOF=a.EOF,this._gracefulProxy={},this._graceful=!1,this.token=null,this.prev=null,this.debug=!1,this.extractDoc=!1,this.suppressErrors=!1,this.lastError=!1,this.startAt=[],this.entries={SCALAR:[this.tok.T_CONSTANT_ENCAPSED_STRING,this.tok.T_START_HEREDOC,this.tok.T_LNUMBER,this.tok.T_DNUMBER,this.tok.T_STRING,this.tok.T_ARRAY,"[",this.tok.T_CLASS_C,this.tok.T_TRAIT_C,this.tok.T_FUNC_C,this.tok.T_METHOD_C,this.tok.T_LINE,this.tok.T_FILE,this.tok.T_DIR,this.tok.T_NS_C,'"','b"','B"',"-",this.tok.T_NS_SEPARATOR],T_MAGIC_CONST:[this.tok.T_CLASS_C,this.tok.T_TRAIT_C,this.tok.T_FUNC_C,this.tok.T_METHOD_C,this.tok.T_LINE,this.tok.T_FILE,this.tok.T_DIR,this.tok.T_NS_C], -T_MEMBER_FLAGS:[this.tok.T_PUBLIC,this.tok.T_PRIVATE,this.tok.T_PROTECTED,this.tok.T_STATIC,this.tok.T_ABSTRACT,this.tok.T_FINAL],VARIABLE:[this.tok.T_VARIABLE,"$",this.tok.T_NS_SEPARATOR,this.tok.T_STRING,this.tok.T_STATIC],EOS:[";",this.tok.T_CLOSE_TAG,this.EOF,this.tok.T_INLINE_HTML],EXPR:["@","-","+","!","~","(","`",this.tok.T_LIST,this.tok.T_CLONE,this.tok.T_INC,this.tok.T_DEC,this.tok.T_NEW,this.tok.T_ISSET,this.tok.T_EMPTY,this.tok.T_INCLUDE,this.tok.T_INCLUDE_ONCE,this.tok.T_REQUIRE,this.tok.T_REQUIRE_ONCE,this.tok.T_EVAL,this.tok.T_INT_CAST,this.tok.T_DOUBLE_CAST,this.tok.T_STRING_CAST,this.tok.T_ARRAY_CAST,this.tok.T_OBJECT_CAST,this.tok.T_BOOL_CAST,this.tok.T_UNSET_CAST,this.tok.T_EXIT,this.tok.T_PRINT,this.tok.T_YIELD,this.tok.T_STATIC,this.tok.T_FUNCTION,this.tok.T_VARIABLE,"$",this.tok.T_NS_SEPARATOR,this.tok.T_STRING,this.tok.T_STRING,this.tok.T_CONSTANT_ENCAPSED_STRING,this.tok.T_START_HEREDOC,this.tok.T_LNUMBER,this.tok.T_DNUMBER,this.tok.T_ARRAY,"[",this.tok.T_CLASS_C,this.tok.T_TRAIT_C,this.tok.T_FUNC_C,this.tok.T_METHOD_C,this.tok.T_LINE,this.tok.T_FILE,this.tok.T_DIR,this.tok.T_NS_C] +},"|":function(){var a=this._input[this.offset];return"="===a?(this.input(),this.tok.T_OR_EQUAL):"|"===a?(this.input(),this.tok.T_BOOLEAN_OR):"|"},"^":function(){return"="===this._input[this.offset]?(this.input(),this.tok.T_XOR_EQUAL):"^"}}}},{}],73:[function(a,b,c){var d=";:,.\\[]()|^&+-/*=%!~$<>?@";b.exports={is_NUM:function(){var a=this._input.charCodeAt(this.offset-1);return a>47&&a<58},is_LABEL:function(){var a=this._input.charCodeAt(this.offset-1);return a>96&&a<123||a>64&&a<91||95===a||a>47&&a<58||a>126},is_LABEL_START:function(){var a=this._input.charCodeAt(this.offset-1);return a>96&&a<123||a>64&&a<91||95===a||a>126},consume_LABEL:function(){for(;this.offset47&&a<58||a>64&&a<71||a>96&&a<103}}},{}],74:[function(a,b,c){function d(a){return"."!=a&&","!=a&&!isNaN(parseFloat(a))&&isFinite(a)}var e=function(a,b){this.lexer=a,this.ast=b,this.tok=a.tok,this.EOF=a.EOF,this._gracefulProxy={},this._graceful=!1,this.token=null,this.prev=null,this.debug=!1,this.extractDoc=!1,this.suppressErrors=!1,this.lastError=!1,this.startAt=[],this.entries={SCALAR:[this.tok.T_CONSTANT_ENCAPSED_STRING,this.tok.T_START_HEREDOC,this.tok.T_LNUMBER,this.tok.T_DNUMBER,this.tok.T_STRING,this.tok.T_ARRAY,"[",this.tok.T_CLASS_C,this.tok.T_TRAIT_C,this.tok.T_FUNC_C,this.tok.T_METHOD_C,this.tok.T_LINE,this.tok.T_FILE,this.tok.T_DIR,this.tok.T_NS_C,'"','b"','B"',"-",this.tok.T_NS_SEPARATOR],T_MAGIC_CONST:[this.tok.T_CLASS_C,this.tok.T_TRAIT_C,this.tok.T_FUNC_C,this.tok.T_METHOD_C,this.tok.T_LINE,this.tok.T_FILE,this.tok.T_DIR,this.tok.T_NS_C], +T_MEMBER_FLAGS:[this.tok.T_PUBLIC,this.tok.T_PRIVATE,this.tok.T_PROTECTED,this.tok.T_STATIC,this.tok.T_ABSTRACT,this.tok.T_FINAL],VARIABLE:[this.tok.T_VARIABLE,"$","&",this.tok.T_NS_SEPARATOR,this.tok.T_STRING,this.tok.T_STATIC],EOS:[";",this.tok.T_CLOSE_TAG,this.EOF,this.tok.T_INLINE_HTML],EXPR:["@","-","+","!","~","(","`",this.tok.T_LIST,this.tok.T_CLONE,this.tok.T_INC,this.tok.T_DEC,this.tok.T_NEW,this.tok.T_ISSET,this.tok.T_EMPTY,this.tok.T_INCLUDE,this.tok.T_INCLUDE_ONCE,this.tok.T_REQUIRE,this.tok.T_REQUIRE_ONCE,this.tok.T_EVAL,this.tok.T_INT_CAST,this.tok.T_DOUBLE_CAST,this.tok.T_STRING_CAST,this.tok.T_ARRAY_CAST,this.tok.T_OBJECT_CAST,this.tok.T_BOOL_CAST,this.tok.T_UNSET_CAST,this.tok.T_EXIT,this.tok.T_PRINT,this.tok.T_YIELD,this.tok.T_STATIC,this.tok.T_FUNCTION,this.tok.T_VARIABLE,"$",this.tok.T_NS_SEPARATOR,this.tok.T_STRING,this.tok.T_STRING,this.tok.T_CONSTANT_ENCAPSED_STRING,this.tok.T_START_HEREDOC,this.tok.T_LNUMBER,this.tok.T_DNUMBER,this.tok.T_ARRAY,"[",this.tok.T_CLASS_C,this.tok.T_TRAIT_C,this.tok.T_FUNC_C,this.tok.T_METHOD_C,this.tok.T_LINE,this.tok.T_FILE,this.tok.T_DIR,this.tok.T_NS_C] }};e.prototype.getTokenName=function(a){return d(a)?a==this.EOF?"the end of file (EOF)":this.lexer.engine.tokens.values[a]:"'"+a+"'"},e.prototype.parse=function(a){this._errors=[],this.currentNamespace=[""],this.lexer.setInput(a),this.lexer.comment_tokens=this.extractDoc,this.length=this.lexer._input.length,this.innerList=!1;var b=this.ast.prepare("program",this),c=[];for(this.nextWithComments();this.token!=this.EOF;){var d=this.read_start();null!==d&&void 0!==d&&(Array.isArray(d)?c=c.concat(d):c.push(d))}return b(c,this._errors)},e.prototype.raiseError=function(a,b,c,d){if(!this.suppressErrors)throw new Error(a);var e=this.ast.prepare("error",this)(a,d,this.lexer.yylloc.first_line,c);return this._errors.push(e),e},e.prototype.error=function(a){var b="Parse Error : syntax error";if(token=this.getTokenName(this.token),this.token!==this.EOF){if(d(this.token)){var c=this.text();c.length>10&&(c=c.substring(0,7)+"..."),token="'"+c+"' ("+token+")"}b+=", unexpected "+token}var e="";return a&&!Array.isArray(a)&&((d(a)||1===a.length)&&(e=", expecting "+this.getTokenName(a)), -b+=e),this.token!==this.EOF,this.raiseError(b+" on line "+this.lexer.yylloc.first_line,e,a,token)},e.prototype.node=function(a){return this.ast.prepare(a,this)},e.prototype.expectEndOfStatement=function(){return";"===this.token?(this.nextWithComments(),this.token===this.tok.T_CLOSE_TAG&&this.nextWithComments()):this.token===this.tok.T_CLOSE_TAG?this.nextWithComments():this.token!==this.tok.T_INLINE_HTML&&this.token!==this.EOF&&this.error(";"),this};var f=["parser.next","parser.nextWithComments"];e.prototype.showlog=function(){for(var a,b=(new Error).stack.split("\n"),c=2;c"+this.lexer.yytext+"< @-->"+a),this},e.prototype.expect=function(a){if(Array.isArray(a)){if(a.indexOf(this.token)===-1)return this.error(a),!1}else if(this.token!=a)return this.error(a),!1;return this},e.prototype.text=function(){ -return this.lexer.yytext},e.prototype.next=function(){return this.debug?(this.showlog(),this.debug=!1,this.nextWithComments().ignoreComments(),this.debug=!0):this.nextWithComments().ignoreComments(),this},e.prototype.ignoreComments=function(){for(this.debug&&this.showlog();this.token===this.tok.T_COMMENT||this.token===this.tok.T_DOC_COMMENT;)this.nextWithComments();return this},e.prototype.nextWithComments=function(){return this.prev=[this.lexer.yylloc.first_line,this.lexer.yylloc.first_column,this.lexer.offset],this.token=this.lexer.lex()||this.EOF,this.debug&&this.showlog(),this},e.prototype.is=function(a){return Array.isArray(a)?a.indexOf(this.token)!==-1:this.entries[a].indexOf(this.token)!=-1},e.prototype.read_token=function(){var a=this.token;return d(a)&&(a=[a,this.text(),this.lexer.yylloc.first_line]),this.next(),a},e.prototype.read_list=function(a,b,c){var d=[];if(this.token==b&&(c&&d.push(""),this.next()),"function"==typeof a){do if(d.push(a.apply(this,[])),this.token!=b)break;while(this.next().token!=this.EOF); -}else for(d.push(this.expect(a).text());this.next().token!=this.EOF&&this.token==b&&this.next().token==a;)d.push(this.text());return d},[a("./parser/array.js"),a("./parser/class.js"),a("./parser/expr.js"),a("./parser/function.js"),a("./parser/if.js"),a("./parser/loops.js"),a("./parser/main.js"),a("./parser/namespace.js"),a("./parser/scalar.js"),a("./parser/statement.js"),a("./parser/switch.js"),a("./parser/try.js"),a("./parser/comment.js"),a("./parser/variable.js")].forEach(function(a){for(var b in a)e.prototype[b]=a[b]}),b.exports=e},{"./parser/array.js":50,"./parser/class.js":51,"./parser/comment.js":52,"./parser/expr.js":53,"./parser/function.js":54,"./parser/if.js":55,"./parser/loops.js":56,"./parser/main.js":57,"./parser/namespace.js":58,"./parser/scalar.js":59,"./parser/statement.js":60,"./parser/switch.js":61,"./parser/try.js":62,"./parser/variable.js":63}],50:[function(a,b,c){var d="array",e="entry";b.exports={read_array:function(){var a=null,b=!1,c=[],e=this.node(d);if(this.expect([this.tok.T_ARRAY,"["]).token==this.tok.T_ARRAY?this.next().expect("("):b=!0, -this.next().token!=a)for(;this.token!=this.EOF&&(c.push(this.read_array_pair_list()),","==this.token)&&(this.next(),this.token!==a););return this.expect(b?"]":")").next(),e(b,c)},read_array_pair_list:function(){var a=this.node(e),b=null,c=null;if("&"===this.token)c=this.next().read_variable(!0,!1,!0);else{var d=this.read_expr();this.token===this.tok.T_DOUBLE_ARROW?(b=d,c="&"===this.next().token?this.next().read_variable(!0,!1,!0):this.read_expr()):c=d}return a(b,c)},read_dim_offset:function(){return"]"!=this.token&&this.read_expr()}}},{}],51:[function(a,b,c){b.exports={read_class:function(a){var b=this.node("class");this.expect(this.tok.T_CLASS).next().expect(this.tok.T_STRING);var c=this.text(),d=!1,e=!1;return this.next().token==this.tok.T_EXTENDS&&(d=this.next().read_namespace_name()),this.token==this.tok.T_IMPLEMENTS&&(e=this.next().read_list(this.read_namespace_name,",")),b(c,a,d,e,this.expect("{").nextWithComments().read_class_body())},read_class_scope:function(){var a=this.token;return a==this.tok.T_FINAL?(this.next(), --1):a==this.tok.T_ABSTRACT?(this.next(),1):0},read_class_body:function(){for(var a=[];this.token!==this.EOF&&"}"!==this.token;)if(this.token!==this.tok.T_COMMENT)if(this.token!==this.tok.T_DOC_COMMENT)if(this.token!==this.tok.T_USE){var b=this.read_member_flags(!1);if(this.token!==this.tok.T_CONST)if(this.token===this.tok.T_VAR&&(this.next().expect(this.tok.T_VARIABLE),b[0]=b[1]=0),this.token===this.tok.T_VARIABLE){var c=this.read_variable_list(b);this.expect(";").nextWithComments();for(var d=0;d>",a,this.next().read_expr()];case this.tok.T_BOOLEAN_OR:case this.tok.T_LOGICAL_OR:return["bool","|",a,this.next().read_expr()];case this.tok.T_BOOLEAN_AND:case this.tok.T_LOGICAL_AND:return["bool","&",a,this.next().read_expr()];case this.tok.T_LOGICAL_XOR:return["bool","^",a,this.next().read_expr()];case this.tok.T_IS_IDENTICAL:return["bool","=",a,this.next().read_expr()];case this.tok.T_IS_NOT_IDENTICAL:return["bool","!=",a,this.next().read_expr()];case this.tok.T_IS_EQUAL:return["bool","~",a,this.next().read_expr()];case this.tok.T_IS_NOT_EQUAL:return["bool","!~",a,this.next().read_expr()];case"<":return["bool","<",a,this.next().read_expr()];case">":return["bool",">",a,this.next().read_expr()]; -case this.tok.T_IS_SMALLER_OR_EQUAL:return["bool","<=",a,this.next().read_expr()];case this.tok.T_IS_GREATER_OR_EQUAL:return["bool",">=",a,this.next().read_expr()];case this.tok.T_SPACESHIP:return["bool","<=>",a,this.next().read_expr()];case this.tok.T_INSTANCEOF:return["bool","?",a,this.next().read_expr()];case this.tok.T_COALESCE:return this.node("coalesce")(a,this.next().read_expr());case"?":var b=null;return":"!==this.next().token&&(b=this.read_expr()),this.expect(":").next(),["retif",a,b,this.read_expr()]}return a},read_expr_item:function(){switch(this.token){case"@":return["silent",this.next().read_expr()];case"-":var a=this.node();return this.next(),this.token===this.tok.T_LNUMBER||this.token===this.tok.T_DNUMBER?(a=a("number","-"+this.text()),this.next(),a):a("unary","-",this.read_expr());case"+":case"!":case"~":return this.node("unary")(this.token,this.read_expr());case"(":var b=this.next().read_expr();return this.expect(")").next(),this.token===this.tok.T_OBJECT_OPERATOR?this.recursive_variable_chain_scan(b,!1):this.token===this.tok.T_CURLY_OPEN||"["===this.token?this.read_dereferencable(b):"("===this.token?this.node("call")(b,this.read_function_argument_list()):b; -case"`":var a=this.node("shell"),b=this.next().read_encapsed_string("`");return a(b);case this.tok.T_LIST:var a=this.node("list");this.next().expect("(").next();var c=this.innerList;this.innerList||(this.innerList=!0);for(var d=this.read_assignment_list(),e=!1,f=0;f>",b,this.next().read_expr()]];case this.tok.T_INC:return this.next(),["post","+",b];case this.tok.T_DEC:return this.next(),["post","-",b]}else if(this.is("SCALAR"))for(b=this.read_scalar();this.token!==this.EOF;)if(this.token===this.tok.T_OBJECT_OPERATOR)b=this.recursive_variable_chain_scan(b,!1);else if(this.token===this.tok.T_CURLY_OPEN||"["===this.token)b=this.read_dereferencable(b);else{ -if("("!==this.token)return b;b=this.node("call")(b,this.read_function_argument_list())}else b=this.error("EXPR"),this.next();return b},read_new_expr:function(){var a=this.node("new");if(this.token===this.tok.T_CLASS){var b=!1,c=!1;return this.next().token==this.tok.T_EXTENDS&&(b=this.next().read_namespace_name()),this.token==this.tok.T_IMPLEMENTS&&(c=this.next().read_list(this.read_namespace_name,",")),a(!1,b,c,this.expect("{").next().read_class_body())}var d=this.read_class_name_reference(),e=[];return"("===this.token&&(e=this.read_function_argument_list()),a(d,e)},read_class_name_reference:function(){if("\\"===this.token||this.token===this.tok.T_STRING){var a=this.read_namespace_name();return a=this.token===this.tok.T_DOUBLE_COLON?this.read_static_getter(a):["ns",a]}return this.is("VARIABLE")?this.read_variable(!0,!1,!1):void this.expect([this.tok.T_STRING,"VARIABLE"])},read_assignment_list:function(){return this.read_list(this.read_assignment_list_element,",")},read_assignment_list_element:function(){if(","===this.token||")"===this.token)return null; -var a=this.read_expr_item();return this.token===this.tok.T_DOUBLE_ARROW&&(a=["key",a,this.next().read_expr_item()]),a}}},{}],54:[function(a,b,c){b.exports={is_reference:function(){return"&"==this.token&&(this.next(),!0)},is_variadic:function(){return this.token===this.tok.T_ELLIPSIS&&(this.next(),!0)},read_function:function(a,b){var c=this.node(this.read_function_declaration(a?1:b?2:0));if(b&&1==b[2])c=c(b),this.expect(";").nextWithComments();else{var d=this.expect("{").read_code_block(!1);c=b?c(d,b):c(d)}return c},read_function_declaration:function(a){var b="function";1===a?b="closure":2===a&&(b="method");var c=this.node(b);this.expect(this.tok.T_FUNCTION);var d=this.next().is_reference(),e=!1,f=[],g=!1;1!==a&&(e=this.expect(this.tok.T_STRING).text(),this.next()),this.expect("(").next();var h=this.read_parameter_list();return this.expect(")").next(),1===a&&this.token===this.tok.T_USE&&(f=this.next().expect("(").next().read_list(this.read_lexical_var,","),this.expect(")").next()),":"===this.token&&(g=this.next().read_type()), -1===a?c(h,d,f,g):c(e,h,d,g)},read_lexical_var:function(){var a=[!1,null];return"&"===this.token&&(a[0]=!0,this.next()),this.token===this.tok.T_VARIABLE?(a[1]=this.text(),this.next()):this.expect(["&",this.tok.T_VARIABLE]),a},read_parameter_list:function(){var a=[];if(")"!=this.token)for(;this.token!=this.EOF;){if(a.push(this.read_parameter()),","!=this.token){if(")"==this.token)break;this.error([",",")"]);break}this.next()}return a},read_parameter:function(){var a=this.node("param"),b=this.read_type(),c=this.is_reference(),d=this.is_variadic(),e=this.expect(this.tok.T_VARIABLE).text(),f=null;return"="==this.next().token&&(f=this.next().read_expr()),a(e,b,f,c,d)},read_function_argument_list:function(){var a=[];if(this.expect("(").next(),")"!==this.token)for(;this.token!=this.EOF&&(a.push(this.read_argument_list()),","===this.token);)this.next();return this.expect(")").next(),a},read_argument_list:function(){return this.token===this.tok.T_ELLIPSIS?this.node("variadic")(this.next().read_expr()):this.read_expr()}, -read_type:function(){switch(this.token){case this.tok.T_ARRAY:return this.next(),["array"];case this.tok.T_NS_SEPARATOR:case this.tok.T_STRING:return this.read_namespace_name();case this.tok.T_CALLABLE:return this.next(),["callable"];default:return null}}}},{}],55:[function(a,b,c){b.exports={read_if:function(){var a=this.node("if"),b=this.read_if_expr(),c=null,d=!1;if(":"===this.token){for(this.next(),c=[];this.token!=this.EOF&&this.token!==this.tok.T_ENDIF;){if(this.ignoreComments(),this.token===this.tok.T_ELSEIF){d=this.next().read_elseif_short();break}if(this.token===this.tok.T_ELSE){d=this.next().read_else_short();break}c.push(this.read_inner_statement())}this.ignoreComments().expect(this.tok.T_ENDIF).next().expectEndOfStatement()}else c=this.read_statement(),this.ignoreComments(),this.token===this.tok.T_ELSEIF?d=this.next().read_if():this.token===this.tok.T_ELSE&&(d=this.next().read_statement());return a(b,c,d)},read_if_expr:function(){this.expect("(").next();var a=this.read_expr();return this.expect(")").next(), -a},read_elseif_short:function(){var a=this.node("if"),b=this.read_if_expr();this.expect(":").next();for(var c=[],d=!1;this.token!=this.EOF&&this.token!==this.tok.T_ENDIF;){if(this.token===this.tok.T_ELSEIF){d=this.next().read_elseif_short();break}if(this.token===this.tok.T_ELSE){d=this.next().read_else_short();break}c.push(this.read_inner_statement())}return a(b,c,d)},read_else_short:function(){this.expect(":").next();for(var a=[];this.token!=this.EOF&&this.token!==this.tok.T_ENDIF;)a.push(this.read_inner_statement());return a}}},{}],56:[function(a,b,c){b.exports={read_short_form:function(a){var b=[];for(this.expect(":").next();this.token!=this.EOF&&this.token!==a;)b.push(this.read_inner_statement());return this.expect(a).next().expectEndOfStatement(),b},read_while:function(){var a=this.node("while");this.expect("(").next();var b=this.read_expr();this.expect(")").next();var c=[];return c=":"===this.token?this.read_short_form(this.tok.T_ENDWHILE):this.read_statement(),a(b,c)},read_do:function(){var a=this.node("do"),b=this.read_statement(); -this.expect(this.tok.T_WHILE).next().expect("(").next();var c=this.read_expr();return this.expect(")").next().expect(";").next(),a(c,b)},read_for:function(){var a=this.node("for");this.expect("(").next();var b=null,c=null,d=null;";"!==this.token?(b=this.read_list(this.read_expr,","),this.expect(";").next()):this.next(),";"!==this.token?(c=this.read_list(this.read_expr,","),this.expect(";").next()):this.next(),")"!==this.token?(d=this.read_list(this.read_expr,","),this.expect(")").next()):this.next();var e=null;return e=":"===this.token?this.read_short_form(this.tok.T_ENDFOR):this.read_statement(),a(b,c,d,e)},read_foreach:function(){var a=this.node("foreach");this.expect("(").next();var b=this.read_expr();this.expect(this.tok.T_AS).next();var c=this.read_foreach_variable(),d=!1;this.token===this.tok.T_DOUBLE_ARROW&&(d=c,c=this.next().read_foreach_variable()),this.expect(")").next();var e=[];return e=":"===this.token?this.read_short_form(this.tok.T_ENDFOREACH):this.read_statement(),a(b,d,c,e)},read_foreach_variable:function(){ -if("&"===this.token)return this.next().read_variable(!1,!1,!0);if(this.token===this.tok.T_LIST){var a=this.node("list");this.next().expect("(").next();var b=this.read_assignment_list();return this.expect(")").next(),a(b,!1)}return this.read_variable(!1,!1,!1)}}},{}],57:[function(a,b,c){b.exports={read_start:function(){return this.token==this.tok.T_NAMESPACE?this.read_namespace():this.read_top_statement()}}},{}],58:[function(a,b,c){b.exports={read_namespace:function(){this.expect(this.tok.T_NAMESPACE).next();var a=this.node("namespace");if("{"==this.token)return this.currentNamespace=[""],a([""],this.read_code_block(!0));this.token===this.tok.T_NAMESPACE&&(this.error(["{",this.tok.T_STRING]),this.next());var b=this.read_namespace_name();if(";"==this.token){this.currentNamespace=b;var c=this.nextWithComments().read_top_statements();return this.expect(this.EOF),a(b,c)}if("{"==this.token)return this.currentNamespace=b,a(b,this.read_code_block(!0));if("("===this.token)return this.node("call")(["ns",b.slice(1)],this.read_function_argument_list()); -this.error(["{",";"]),this.currentNamespace=b;var c=this.read_top_statements();return this.expect(this.EOF),a(b,c)},read_namespace_name:function(){return this.token===this.tok.T_NAMESPACE&&this.next().expect(this.tok.T_NS_SEPARATOR).next(),this.read_list(this.tok.T_STRING,this.tok.T_NS_SEPARATOR,!0)},read_use_statements:function(){for(var a=[];this.token!==this.EOF&&(this.expect(this.tok.T_USE).next(),this.read_list(this.read_use_statement_mixed,",").forEach(function(b){Array.isArray(b)?a=a.concat(b):a.push(b)}),this.token===this.tok.T_USE););return a},read_inline_use_declaration:function(a){for(var b=[];this.token!==this.EOF;){var c=this.node("use"),d=this.read_use_statement(a[3]!==!1);if(this.token===this.tok.T_AS&&(this.next().expect(this.tok.T_STRING),d[1]=this.text(),this.next()),d[0]=a[0].concat(d[0]),a[2]!==!1&&(d[2]=a[2]),b.push(c.apply(this,d)),","!==this.token)break;this.next()}return b},read_use_statement_mixed:function(){var a=this.node("use"),b=this.read_use_statement();if(this.token===this.tok.T_AS)this.next().expect(this.tok.T_STRING), -b[1]=this.text(),this.next();else if("{"===this.token)return b=this.next().read_inline_use_declaration(b),this.expect("}").next(),b;return a.apply(this,b)},read_use_statement:function(a){var b=!1;a||this.token!==this.tok.T_FUNCTION&&this.token!==this.tok.T_CONST||(b=this.token===this.tok.T_FUNCTION?"function":"constant",this.next());var c=this.read_namespace_name();return[c,c[c.length-1],b]}}},{}],59:[function(a,b,c){var d={"\\r":"\r","\\n":"\n","\\t":"\t","\\v":String.fromCharCode(11),"\\e":String.fromCharCode(27),"\\f":String.fromCharCode(12),"\\\\":"\\","\\$":"$",'\\"':'"',"\\'":"'"};b.exports={resolve_special_chars:function(a){return a.replace(/\\[rntvef"'\\\$]/g,function(a){return d[a]})},read_scalar:function(){if(this.is("T_MAGIC_CONST"))return this.get_magic_constant();switch(this.token){case this.tok.T_CONSTANT_ENCAPSED_STRING:var a=this.node("string"),b=this.text(),c=!1,d="b"===a[0]||"B"===a[0];return d?(c='"'===b[1],b=b.substring(2,b.length-1)):(c='"'===b[0],b=b.substring(1,b.length-1)),a=a(c,this.resolve_special_chars(b)), -d&&(a=["cast","binary",a]),this.next(),this.token===this.tok.T_DOUBLE_COLON?this.read_static_getter(a):a;case this.tok.T_START_HEREDOC:return this.next().read_encapsed_string(this.tok.T_END_HEREDOC);case'"':return this.next().read_encapsed_string('"');case'b"':case'B"':return["cast","binary",this.next().read_encapsed_string('"')];case"-":case this.tok.T_LNUMBER:case this.tok.T_DNUMBER:var e=this.node("number"),a=this.text();return"-"===this.token&&(this.next().expect([this.tok.T_LNUMBER,this.tok.T_DNUMBER]),a+=this.text()),e=e(a),this.next(),e;case this.tok.T_NAMESPACE:case this.tok.T_NS_SEPARATOR:case this.tok.T_STRING:var a=this.read_namespace_name(),e=["constant",a];for(this.token==this.tok.T_DOUBLE_COLON&&(this.next().expect([this.tok.T_STRING,this.tok.T_CLASS]),e[1]=[a,this.text()],this.next());"["===this.token;)e=["offset",e,this.next().read_expr()],this.expect("]").next();return e;case this.tok.T_ARRAY:case"[":return this.read_array();default:var f=this.error("SCALAR");return this.next(),f}},read_dereferencable:function(a){ -var b;return"["===this.token?(b=["offset",a,this.next().read_expr()],this.expect("]").next()):this.token===this.tok.T_DOLLAR_OPEN_CURLY_BRACES&&(b=["offset",a,this.read_encapsed_string_item()]),b},read_encapsed_string_item:function(){var a=null;return this.token===this.tok.T_ENCAPSED_AND_WHITESPACE?(a=this.node("string")(!1,this.text()),this.next()):this.token===this.tok.T_DOLLAR_OPEN_CURLY_BRACES?(this.next().token===this.tok.T_STRING_VARNAME?(a=["var",this.text()],"["===this.next().token&&(a=["offset",a,this.next().read_expr()],this.expect("]").next())):a=this.read_expr(),this.expect("}").next()):this.token===this.tok.T_CURLY_OPEN?(a=this.next().read_variable(!1,!1,!1),this.expect("}").next()):"["===this.token?(a=["offset",a,this.next().read_expr()],this.expect("]").next()):this.token===this.tok.T_VARIABLE?a=this.read_variable(!1,!0,!1):this.expect([this.tok.T_VARIABLE,this.tok.T_CURLY_OPEN,this.tok.T_DOLLAR_OPEN_CURLY_BRACES,this.tok.T_ENCAPSED_AND_WHITESPACE]),a},read_encapsed_string:function(a){if(this.token===a)return this.next(), -null;var b=this.read_encapsed_string_item();if(this.token===a)return this.next(),b;for(var c=["bin",".",b,this.read_encapsed_string_item()];this.token!==a;)c[3]=["bin",".",c[3],this.read_encapsed_string_item()];return this.expect(a).next(),c},get_magic_constant:function(){var a=this.node("magic"),b=this.text();return this.next(),a(b)}}},{}],60:[function(a,b,c){b.exports={read_top_statements:function(){for(var a=[];this.token!==this.EOF&&"}"!==this.token;){var b=this.read_top_statement();b&&(Array.isArray(b)?a=a.concat(b):a.push(b))}return a},read_top_statement:function(){switch(this.token){case this.tok.T_FUNCTION:return this.read_function();case this.tok.T_ABSTRACT:case this.tok.T_FINAL:var a=this.read_class_scope();switch(this.token){case this.tok.T_CLASS:return this.read_class(a);case this.tok.T_INTERFACE:return this.read_interface(a);default:var b=this.error([this.tok.T_CLASS,this.tok.T_INTERFACE]);return this.next(),b}case this.tok.T_CLASS:return this.read_class(0);case this.tok.T_INTERFACE:return this.read_interface(0); -case this.tok.T_TRAIT:return this.read_trait();case this.tok.T_USE:var c=this.read_use_statements();return this.expect(";").nextWithComments(),c;case this.tok.T_CONST:return this.next().read_const_list();case this.tok.T_NAMESPACE:return this.read_namespace();case this.tok.T_HALT_COMPILER:var d=this.node("halt");return this.next().expect("(").next().expect(")").next().expect(";"),this.lexer.done=!0,d(this.lexer._input.substring(this.lexer.offset));default:return this.read_statement()}},read_inner_statements:function(){for(var a=[];this.token!=this.EOF&&"}"!==this.token;){var b=this.read_inner_statement();b&&(Array.isArray(b)?a=a.concat(b):a.push(b))}return a},read_const_list:function(){var a=this.read_list(function(){this.expect(this.tok.T_STRING);var a=this.node("constant"),b=this.text();return this.next().expect("=").next(),a(b,this.read_expr())},",",!1);return this.expectEndOfStatement(),a},read_declare_list:function(){return this.read_list(function(){this.expect(this.tok.T_STRING);var a=this.text();return this.next().expect("=").next(), -[a,this.read_expr()]},",")},read_inner_statement:function(){switch(this.token){case this.tok.T_FUNCTION:return this.read_function();case this.tok.T_ABSTRACT:case this.tok.T_FINAL:var a=this.read_class_scope();switch(this.token){case this.tok.T_CLASS:return this.read_class(a);case this.tok.T_INTERFACE:return this.read_interface(a);default:var b=this.error([this.tok.T_CLASS,this.tok.T_INTERFACE]);return this.next(),b}case this.tok.T_CLASS:return this.read_class(0);case this.tok.T_INTERFACE:return this.read_interface(0);case this.tok.T_TRAIT:return this.read_trait();case this.tok.T_HALT_COMPILER:this.next().expect("(").next().expect(")").next().expect(";").next(),this.raiseError("__HALT_COMPILER() can only be used from the outermost scope");default:return this.read_statement()}},read_statement:function(){switch(this.token){case"{":return this.read_code_block(!1);case this.tok.T_IF:return this.next().read_if();case this.tok.T_SWITCH:return this.read_switch();case this.tok.T_FOR:return this.next().read_for();case this.tok.T_FOREACH: -return this.next().read_foreach();case this.tok.T_WHILE:return this.next().read_while();case this.tok.T_DO:return this.next().read_do();case this.tok.T_COMMENT:return this.read_comment();case this.tok.T_DOC_COMMENT:return this.read_doc_comment();case this.tok.T_RETURN:case this.tok.T_BREAK:case this.tok.T_CONTINUE:var a;switch(this.token){case this.tok.T_RETURN:a="return";break;case this.tok.T_BREAK:a="break";break;case this.tok.T_CONTINUE:a="continue"}var b=null;return this.next().is("EOS")||(b=this.read_expr()),this.expectEndOfStatement(),[a,b];case this.tok.T_GLOBAL:var c=this.next().read_list(this.read_simple_variable,",");return this.expectEndOfStatement(),["global",c];case this.tok.T_STATIC:var d=[this.token,this.lexer.getState()],e=this.node("static");if(this.next().token===this.tok.T_DOUBLE_COLON){this.lexer.tokens.push(d);var b=this.next().read_expr();return this.expect(";").nextWithComments(),b}var c=this.read_list(function(){var a=this.expect(this.tok.T_VARIABLE).text(),b=null;return"="===this.next().token&&(b=this.next().read_expr()), -[a,b]},",");return this.expectEndOfStatement(),e("declare",c);case this.tok.T_ECHO:var e=this.node("echo"),f="("===this.next().token;f&&this.next();var g=this.read_list(this.read_expr,",");return f&&this.expect(")").next(),this.expectEndOfStatement(),e(g);case this.tok.T_INLINE_HTML:var e=this.node("inline")(this.text());return this.next(),e;case this.tok.T_UNSET:var e=this.node("unset");this.next().expect("(").next();var c=this.read_list(this.read_variable,",");return this.expect(")").next().expect(";")?(e=e(c),this.nextWithComments()):e=e(c),e;case this.tok.T_DECLARE:var h,i,e=this.node("declare");if(this.next().expect("(").next(),h=this.read_declare_list(),this.expect(")").nextWithComments(),":"===this.token){for(i=[],this.next();this.token!=this.EOF&&this.token!==this.tok.T_ENDDECLARE;)i.push(this.read_statement());this.ignoreComments().expect(this.tok.T_ENDDECLARE).next().expectEndOfStatement()}else i=this.read_statement();return e(h,i);case this.tok.T_TRY:return this.read_try();case this.tok.T_THROW:var e=this.node("throw"),b=this.next().read_expr(); -return this.expectEndOfStatement(),e(b);case";":case this.tok.T_CLOSE_TAG:return this.next(),null;case this.tok.T_STRING:var d=[this.token,this.lexer.getState()],j=this.text();if(":"===this.next().token){var e=this.node("label");return this.next(),e(j)}this.lexer.tokens.push(d);var b=this.next().read_expr();return this.expect([";",this.tok.T_CLOSE_TAG]).nextWithComments(),b;case this.tok.T_GOTO:var e=this.node("goto"),j=this.next().expect(this.tok.T_STRING).text();return this.next().expectEndOfStatement(),e(j);default:var b=this.read_expr();return this.expectEndOfStatement(),b}},read_code_block:function(a){this.expect("{").nextWithComments();var b=a?this.read_top_statements():this.read_inner_statements();return this.expect("}").nextWithComments(),b}}},{}],61:[function(a,b,c){b.exports={read_switch:function(){this.expect(this.tok.T_SWITCH).next();var a=this.node("switch");this.expect("(").next();var b=this.read_expr();this.expect(")").next();var c=this.read_switch_case_list();return a(b,c)},read_switch_case_list:function(){ -var a=null,b=[];for("{"===this.token?a="}":":"===this.token?a=this.tok.T_ENDSWITCH:this.expect(["{",":"]),this.next(),";"===this.token&&this.next(),this.token===this.tok.T_CLOSE_TAG&&this.next();this.token!==this.EOF&&this.token!==a;)b.push(this.read_case_list(a));return this.expect(a).next(),a===this.tok.T_ENDSWITCH&&this.expectEndOfStatement(),b},read_case_list:function(a){var b={condition:!1,body:[]};for(this.token===this.tok.T_CASE?b.condition=this.next().read_expr():this.token===this.tok.T_DEFAULT?this.next():this.expect([this.tok.T_CASE,this.tok.T_DEFAULT]),this.expect([":",";"]).next();this.token!=this.EOF&&this.token!==a&&this.token!==this.tok.T_CASE&&this.token!==this.tok.T_DEFAULT;)b.body.push(this.read_inner_statement());return b}}},{}],62:[function(a,b,c){b.exports={read_try:function(){this.expect(this.tok.T_TRY);var a=this.node("try"),b=this.nextWithComments().read_statement(),c=!1,d=[];for(this.ignoreComments();this.token===this.tok.T_CATCH;){this.next().expect("(").next();var e=this.read_namespace_name(),f=this.read_variable(!0,!1,!1); -this.expect(")").nextWithComments(),d.push({exception:e,as:f,body:this.read_statement()}),this.ignoreComments()}return this.token===this.tok.T_FINALLY&&(c=this.nextWithComments().read_statement()),a(b,d,c)}}},{}],63:[function(a,b,c){b.exports={read_variable:function(a,b,c){var d;if(this.is([this.tok.T_VARIABLE,"$"]))d=this.read_reference_variable(b,c);else if(this.is([this.tok.T_NS_SEPARATOR,this.tok.T_STRING])){d=this.node();var e=this.read_namespace_name();if(this.token!=this.tok.T_DOUBLE_COLON&&"("!=this.token)if(1==e.length){var f=e[0].toLowerCase();d="true"===f?d("boolean",!0):"false"===f?d("boolean",!1):["constant",e[0]]}else d=["constant",e];else d=["ns",d]}else this.token===this.tok.T_STATIC?(this.next(),d=["ns",["static"]]):this.expect("VARIABLE");return this.token===this.tok.T_DOUBLE_COLON&&(d=this.read_static_getter(d,b)),this.recursive_variable_chain_scan(d,a,b)},read_static_getter:function(a,b){var c=null;return this.next().is([this.tok.T_VARIABLE,"$"])?c=this.read_reference_variable(b,!1):this.token===this.tok.T_STRING||this.token===this.tok.T_CLASS?(c=this.text(), -this.next()):(c=this.error([this.tok.T_VARIABLE,this.tok.T_STRING]),this.next()),"ns"!=a[0]&&(a=["lookup","class",a]),["static","get",a,c]},recursive_variable_chain_scan:function(a,b,c){a:for(;this.token!=this.EOF;)switch(this.token){case"(":if(b)return a;a=["call",a,this.read_function_argument_list()];break;case"[":this.next();var d=!1;c?(d=this.read_encaps_var_offset(),this.expect("]").next()):"]"!==this.token?(d=this.read_expr(),this.expect("]").next()):this.next(),a=["offset",a,d];break;case this.tok.T_OBJECT_OPERATOR:var e;switch(this.next().token){case this.tok.T_STRING:e=["string",this.text()];var f=this.next().token;f===this.tok.T_VARIABLE?e=["bin",".",e,["var",this.text()]]:"{"===f&&(e=["bin",".",e,this.next().read_expr()],this.expect("}").next());break;case this.tok.T_VARIABLE:e=["var",this.text()],this.next();break;case"$":this.next().expect(["{",this.tok.T_VARIABLE]),"{"===this.token?(e=this.next().read_expr(),this.expect("}").next()):e=this.read_expr();break;case"{":e=this.next().read_expr(),this.expect("}").next(); -break;default:e=this.error([this.tok.T_STRING,this.tok.T_VARIABLE]),this.next()}a=["prop",a,e];break;default:break a}return a},read_encaps_var_offset:function(){var a=this.node();if(this.token===this.tok.T_STRING){var b=this.text(),c='"'===b[0];b=b.substring(1,b.length-1),a=a("string",c,this.resolve_special_chars(b))}else this.token===this.tok.T_NUM_STRING?a=a("number",this.text()):this.token===this.tok.T_VARIABLE?a=a("variable",this.text()):this.expect([this.tok.T_STRING,this.tok.T_NUM_STRING,this.tok.T_VARIABLE]);return this.next(),a},read_reference_variable:function(a,b){for(var c=this.read_simple_variable(b);this.token!=this.EOF;)if("["==this.token){if(a)c=this.next().read_encaps_var_offset();else{var d="]"===this.next().token?null:this.read_dim_offset();c=["offset",c,d]}this.expect("]").next()}else{if("{"!=this.token||a)break;c=["offset",c,this.next().read_expr()],this.expect("}").next()}return c},read_simple_variable:function(a){var b=this.node("variable");if(this.expect([this.tok.T_VARIABLE,"$"]).token===this.tok.T_VARIABLE)b=b(this.text(),a), -this.next();else{switch(this.next().token){case"{":b=this.next().read_expr(),this.expect("}").next();break;case"$":b=["lookup","var",this.read_simple_variable(!1)];break;case this.tok.T_VARIABLE:b=["var",this.text()],this.next();break;default:b=this.error(["{","$",this.tok.T_VARIABLE]),this.next()}b=["lookup","var",b]}return b}}},{}],64:[function(a,b,c){b.exports={values:{101:"T_HALT_COMPILER",102:"T_USE",103:"T_ENCAPSED_AND_WHITESPACE",104:"T_OBJECT_OPERATOR",105:"T_STRING",106:"T_DOLLAR_OPEN_CURLY_BRACES",107:"T_STRING_VARNAME",108:"T_CURLY_OPEN",109:"T_NUM_STRING",110:"T_ISSET",111:"T_EMPTY",112:"T_INCLUDE",113:"T_INCLUDE_ONCE",114:"T_EVAL",115:"T_REQUIRE",116:"T_REQUIRE_ONCE",117:"T_NAMESPACE",118:"T_NS_SEPARATOR",119:"T_AS",120:"T_IF",121:"T_ENDIF",122:"T_WHILE",123:"T_DO",124:"T_FOR",125:"T_SWITCH",126:"T_BREAK",127:"T_CONTINUE",128:"T_RETURN",129:"T_GLOBAL",130:"T_STATIC",131:"T_ECHO",132:"T_INLINE_HTML",133:"T_UNSET",134:"T_FOREACH",135:"T_DECLARE",136:"T_TRY",137:"T_THROW",138:"T_GOTO",139:"T_FINALLY", +b+=e),this.token!==this.EOF,this.raiseError(b+" on line "+this.lexer.yylloc.first_line,e,a,token)},e.prototype.node=function(a){return this.ast.prepare(a,this)},e.prototype.expectEndOfStatement=function(){if(";"===this.token)this.nextWithComments(),this.token===this.tok.T_CLOSE_TAG&&this.nextWithComments();else if(this.token===this.tok.T_CLOSE_TAG)this.nextWithComments();else if(this.token!==this.tok.T_INLINE_HTML&&this.token!==this.EOF)return this.error(";"),!1;return!0};var f=["parser.next","parser.nextWithComments"];e.prototype.showlog=function(){for(var a,b=(new Error).stack.split("\n"),c=2;c"+this.lexer.yytext+"< @-->"+a),this},e.prototype.expect=function(a){if(Array.isArray(a)){if(a.indexOf(this.token)===-1)return this.error(a),!1}else if(this.token!=a)return this.error(a),!1;return!0},e.prototype.text=function(){ +return this.lexer.yytext},e.prototype.next=function(){return this.debug?(this.showlog(),this.debug=!1,this.nextWithComments().ignoreComments(),this.debug=!0):this.nextWithComments().ignoreComments(),this},e.prototype.ignoreComments=function(){for(this.debug&&this.showlog();this.token===this.tok.T_COMMENT||this.token===this.tok.T_DOC_COMMENT;)this.nextWithComments();return this},e.prototype.nextWithComments=function(){return this.prev=[this.lexer.yylloc.first_line,this.lexer.yylloc.first_column,this.lexer.offset],this.token=this.lexer.lex()||this.EOF,this.debug&&this.showlog(),this},e.prototype.is=function(a){return Array.isArray(a)?a.indexOf(this.token)!==-1:this.entries[a].indexOf(this.token)!=-1},e.prototype.read_token=function(){var a=this.token;return d(a)&&(a=[a,this.text(),this.lexer.yylloc.first_line]),this.next(),a},[a("./parser/array.js"),a("./parser/class.js"),a("./parser/comment.js"),a("./parser/expr.js"),a("./parser/function.js"),a("./parser/if.js"),a("./parser/loops.js"),a("./parser/main.js"),a("./parser/namespace.js"),a("./parser/scalar.js"),a("./parser/statement.js"),a("./parser/switch.js"),a("./parser/try.js"),a("./parser/utils.js"),a("./parser/variable.js")].forEach(function(a){ +for(var b in a)e.prototype[b]=a[b]}),b.exports=e},{"./parser/array.js":75,"./parser/class.js":76,"./parser/comment.js":77,"./parser/expr.js":78,"./parser/function.js":79,"./parser/if.js":80,"./parser/loops.js":81,"./parser/main.js":82,"./parser/namespace.js":83,"./parser/scalar.js":84,"./parser/statement.js":85,"./parser/switch.js":86,"./parser/try.js":87,"./parser/utils.js":88,"./parser/variable.js":89}],75:[function(a,b,c){var d="array",e="entry";b.exports={read_array:function(){var a=null,b=!1,c=[],e=this.node(d);if(this.expect([this.tok.T_ARRAY,"["]),this.token==this.tok.T_ARRAY?this.next().expect("("):b=!0,this.next().token!=a)for(;this.token!=this.EOF&&(c.push(this.read_array_pair_list()),","==this.token)&&(this.next(),this.token!==a););return this.expect(b?"]":")"),this.next(),e(b,c)},read_array_pair_list:function(){var a=this.node(e),b=null,c=null;if("&"===this.token)c=this.next().read_variable(!0,!1,!0);else{var d=this.read_expr();this.token===this.tok.T_DOUBLE_ARROW?(b=d,c="&"===this.next().token?this.next().read_variable(!0,!1,!0):this.read_expr()):c=d; +}return a(b,c)},read_dim_offset:function(){return"]"!=this.token&&this.read_expr()}}},{}],76:[function(a,b,c){b.exports={read_class:function(a){var b=this.node("class");this.expect(this.tok.T_CLASS),this.next().expect(this.tok.T_STRING);var c,d=this.text(),e=null,f=null;return this.next().token==this.tok.T_EXTENDS&&(e=this.next().read_namespace_name()),this.token==this.tok.T_IMPLEMENTS&&(f=this.next().read_name_list()),this.expect("{"),c=this.nextWithComments().read_class_body(),b(d,e,f,c,a)},read_class_scope:function(){var a=this.token;return a==this.tok.T_FINAL?(this.next(),[0,0,2]):a==this.tok.T_ABSTRACT?(this.next(),[0,0,1]):[0,0,0]},read_class_body:function(){for(var a=[];this.token!==this.EOF&&"}"!==this.token;)if(this.token!==this.tok.T_COMMENT)if(this.token!==this.tok.T_DOC_COMMENT)if(this.token!==this.tok.T_USE){var b=this.read_member_flags(!1);if(this.token!==this.tok.T_CONST)if(this.token===this.tok.T_VAR&&(this.next().expect(this.tok.T_VARIABLE),b[0]=b[1]=0),this.token===this.tok.T_VARIABLE){var c=this.read_variable_list(b); +this.expect(";"),this.nextWithComments(),a=a.concat(c)}else this.token===this.tok.T_FUNCTION?a.push(this.read_function(!1,b)):(this.error([this.tok.T_CONST,this.tok.T_VARIABLE,this.tok.T_FUNCTION]),this.next());else{var d=this.read_constant_list(b);this.expect(";"),this.nextWithComments(),a=a.concat(d)}}else a=a.concat(this.next().read_trait_use_statement());else a.push(this.read_doc_comment());else a.push(this.read_comment());return this.expect("}"),this.nextWithComments(),a},read_variable_list:function(a){return this.read_list(function(){var b=this.node("property");this.expect(this.tok.T_VARIABLE);var c=this.text();return this.next(),";"===this.token||","===this.token?b(c,null,a):"="===this.token?b(c,this.next().read_expr(),a):(this.expect([",",";","="]),b(c,null,a))},",")},read_constant_list:function(a){return this.expect(this.tok.T_CONST)&&this.next(),this.read_list(function(){var b=this.node("classconstant"),c=null,d=null;return this.expect(this.tok.T_STRING)&&(c=this.text(),this.next()),this.expect("=")&&(d=this.next().read_expr()), +b(c,d,a)},",")},read_member_flags:function(a){var b=[-1,-1,-1];if(this.is("T_MEMBER_FLAGS")){var c=0,d=0;do{switch(this.token){case this.tok.T_PUBLIC:c=0,d=0;break;case this.tok.T_PROTECTED:c=0,d=1;break;case this.tok.T_PRIVATE:c=0,d=2;break;case this.tok.T_STATIC:c=1,d=1;break;case this.tok.T_ABSTRACT:c=2,d=1;break;case this.tok.T_FINAL:c=2,d=2}a&&(0==c&&2==d?(this.expect([this.tok.T_PUBLIC,this.tok.T_PROTECTED]),d=-1):2==c&&1==d&&(this.error(),d=-1)),b[c]!==-1?this.error():d!==-1&&(b[c]=d)}while(this.next().is("T_MEMBER_FLAGS"))}return b[0]==-1&&(b[0]=0),b[1]==-1&&(b[1]=0),b[2]==-1&&(b[2]=0),b},read_interface:function(){var a=this.node("interface"),b=null,c=null,d=null;return this.expect(this.tok.T_INTERFACE)&&this.next(),this.expect(this.tok.T_STRING)&&(b=this.text(),this.next()),this.token===this.tok.T_EXTENDS&&(d=this.next().read_name_list()),this.expect("{")&&(c=this.next().read_interface_body()),a(b,d,c)},read_interface_body:function(){for(var a=[];this.token!==this.EOF&&"}"!==this.token;)if(this.token!==this.tok.T_COMMENT)if(this.token!==this.tok.T_DOC_COMMENT){ +var b=this.read_member_flags(!0);if(this.token==this.tok.T_CONST){var c=this.read_constant_list(b);this.expect(";")&&this.nextWithComments(),a=a.concat(c)}else if(this.token===this.tok.T_FUNCTION){var d=this.read_function_declaration(2,b);d.parseFlags(b),a.push(d),this.expect(";")&&this.nextWithComments()}else this.error([this.tok.T_CONST,this.tok.T_FUNCTION]),this.next()}else a.push(this.read_doc_comment());else a.push(this.read_comment());return this.expect("}")&&this.next(),a},read_trait:function(a){var b=this.node("trait"),c=null,d=null,e=null,f=null;return this.expect(this.tok.T_TRAIT)&&this.next(),this.expect(this.tok.T_STRING)&&(c=this.text()),this.next().token==this.tok.T_EXTENDS&&(d=this.next().read_namespace_name()),this.token==this.tok.T_IMPLEMENTS&&(e=this.next().read_name_list()),this.expect("{")&&(f=this.next().read_class_body()),b(c,d,e,f)},read_trait_use_statement:function(){for(var a=this.node("traituse"),b=[this.read_namespace_name()],c=null;","===this.token;)b.push(this.next().read_namespace_name()); +if("{"===this.token){for(c=[];this.next().token!==this.EOF&&"}"!==this.token;)c.push(this.read_trait_use_alias()),this.expect(";");this.expect("}")&&this.nextWithComments()}else this.expect(";")&&this.nextWithComments();return a(b,c)},read_trait_use_alias:function(){var a=this.node(),b=null,c=this.read_namespace_name();if(this.token===this.tok.T_DOUBLE_COLON?this.next().expect(this.tok.T_STRING)&&(b=c,c=this.text(),this.next()):c=c.name,this.token===this.tok.T_INSTEADOF)return a("traitprecedence",b,c,this.next().read_name_list());if(this.token===this.tok.T_AS){var d=!1,e=null;return this.next().is("T_MEMBER_FLAGS")&&(d=this.read_member_flags()),this.token===this.tok.T_STRING?(e=this.text(),this.next()):d===!1&&this.expect(this.tok.T_STRING),a("traitalias",b,c,e,d)}return this.expect([this.tok.T_AS,this.tok.T_INSTEADOF]),a("traitalias",b,c,null,null)}}},{}],77:[function(a,b,c){var d=/^(\s*\*[ \t]*|[ \t]*)(.*)$/gm;b.exports={read_comment:function(){var a=this.node("doc"),b=[];do{var c=this.text();"#"===c[0]?c=c.substring(1):(c=c.substring(2), +"*/"===c.substring(c.length-2)&&(c=c.substring(0,c.length-2))),b.push(c.trim())}while(this.nextWithComments().token===this.tok.T_COMMENT);return a(!1,b)},read_doc_comment:function(){var a=this.node("doc"),b=this.text();b=b.substring(2,b.length-2);var c=[];b=b.split(d);for(var e=2;e>",a,this.next().read_expr()];case this.tok.T_BOOLEAN_OR:case this.tok.T_LOGICAL_OR:return["bool","|",a,this.next().read_expr()];case this.tok.T_BOOLEAN_AND:case this.tok.T_LOGICAL_AND:return["bool","&",a,this.next().read_expr()];case this.tok.T_LOGICAL_XOR:return["bool","^",a,this.next().read_expr()];case this.tok.T_IS_IDENTICAL:return["bool","=",a,this.next().read_expr()];case this.tok.T_IS_NOT_IDENTICAL:return["bool","!=",a,this.next().read_expr()];case this.tok.T_IS_EQUAL:return["bool","~",a,this.next().read_expr()];case this.tok.T_IS_NOT_EQUAL:return["bool","!~",a,this.next().read_expr()];case"<":return["bool","<",a,this.next().read_expr()];case">":return["bool",">",a,this.next().read_expr()];case this.tok.T_IS_SMALLER_OR_EQUAL:return["bool","<=",a,this.next().read_expr()];case this.tok.T_IS_GREATER_OR_EQUAL:return["bool",">=",a,this.next().read_expr()];case this.tok.T_SPACESHIP:return["bool","<=>",a,this.next().read_expr()];case this.tok.T_INSTANCEOF: +return["bool","?",a,this.next().read_expr()];case this.tok.T_COALESCE:return this.node("coalesce")(a,this.next().read_expr());case"?":var b=null;return":"!==this.next().token&&(b=this.read_expr()),this.expect(":")&&this.next(),["retif",a,b,this.read_expr()]}return a},read_expr_item:function(){switch(this.token){case"@":return["silent",this.next().read_expr()];case"-":var a=this.node();return this.next(),this.token===this.tok.T_LNUMBER||this.token===this.tok.T_DNUMBER?(a=a("number","-"+this.text()),this.next(),a):a("unary","-",this.read_expr());case"+":case"!":case"~":return this.node("unary")(this.token,this.read_expr());case"(":var b=this.next().read_expr();return this.expect(")")&&this.next(),this.token===this.tok.T_OBJECT_OPERATOR?this.recursive_variable_chain_scan(b,!1):this.token===this.tok.T_CURLY_OPEN||"["===this.token?this.read_dereferencable(b):"("===this.token?this.node("call")(b,this.read_function_argument_list()):b;case"`":var a=this.node("shell"),b=this.next().read_encapsed_string("`");return a(b); +case this.tok.T_LIST:var a=this.node("list"),c=null,d=this.innerList;d||(c=this.node("assign")),this.next().expect("(")&&this.next(),this.innerList||(this.innerList=!0);for(var e=this.read_assignment_list(),f=!1,g=0;g>",b,this.next().read_expr()]];case this.tok.T_INC:var a=this.node("post");return this.next(),a("+",b);case this.tok.T_DEC:var a=this.node("post");return this.next(),a("+",b)}else if(this.is("SCALAR"))for(b=this.read_scalar();this.token!==this.EOF;)if(this.token===this.tok.T_OBJECT_OPERATOR)b=this.recursive_variable_chain_scan(b,!1);else if(this.token===this.tok.T_CURLY_OPEN||"["===this.token)b=this.read_dereferencable(b);else{ +if("("!==this.token)return b;b=this.node("call")(b,this.read_function_argument_list())}else b=this.error("EXPR"),this.next();return b},read_new_expr:function(){var a=this.node("new");if(this.token===this.tok.T_CLASS){var b=null,c=null,d=null;return this.next().token==this.tok.T_EXTENDS&&(b=this.next().read_namespace_name()),this.token==this.tok.T_IMPLEMENTS&&(c=this.next().read_name_list()),this.expect("{")&&(d=this.next().read_class_body()),a(!1,b,c,d)}var e=this.read_class_name_reference(),f=[];return"("===this.token&&(f=this.read_function_argument_list()),a(e,f)},read_class_name_reference:function(){if("\\"===this.token||this.token===this.tok.T_STRING){var a=this.read_namespace_name();return a=this.token===this.tok.T_DOUBLE_COLON?this.read_static_getter(a):["ns",a]}return this.is("VARIABLE")?this.read_variable(!0,!1,!1):void this.expect([this.tok.T_STRING,"VARIABLE"])},read_assignment_list:function(){return this.read_list(this.read_assignment_list_element,",")},read_assignment_list_element:function(){if(","===this.token||")"===this.token)return null; +var a=this.read_expr_item();return this.token===this.tok.T_DOUBLE_ARROW&&(a=["key",a,this.next().read_expr_item()]),a}}},{}],79:[function(a,b,c){b.exports={is_reference:function(){return"&"==this.token&&(this.next(),!0)},is_variadic:function(){return this.token===this.tok.T_ELLIPSIS&&(this.next(),!0)},read_function:function(a,b){var c=this.read_function_declaration(a?1:b?2:0);return b&&1==b[2]?(c.parseFlags(b),this.expect(";")&&this.nextWithComments()):(this.expect("{")&&(c.body=this.read_code_block(!1)),b&&c.parseFlags(b)),c},read_function_declaration:function(a){var b="function";1===a?b="closure":2===a&&(b="method");var c=this.node(b);this.expect(this.tok.T_FUNCTION)&&this.next();var d=this.is_reference(),e=!1,f=[],g=!1;1!==a&&this.expect(this.tok.T_STRING)&&(e=this.text(),this.next()),this.expect("(")&&this.next();var h=this.read_parameter_list();return this.expect(")")&&this.next(),1===a&&this.token===this.tok.T_USE&&(this.next().expect("(")&&this.next(),f=this.read_list(this.read_lexical_var,","),this.expect(")")&&this.next()), +":"===this.token&&(g=this.next().read_type()),1===a?c(h,d,f,g):c(e,h,d,g)},read_lexical_var:function(){var a=[!1,null];return"&"===this.token&&(a[0]=!0,this.next()),this.token===this.tok.T_VARIABLE?(a[1]=this.text(),this.next()):this.expect(["&",this.tok.T_VARIABLE]),a},read_parameter_list:function(){var a=[];if(")"!=this.token)for(;this.token!=this.EOF;){if(a.push(this.read_parameter()),","!=this.token){if(")"==this.token)break;this.error([",",")"]);break}this.next()}return a},read_parameter:function(){var a=this.node("parameter"),b=null,c=null,d=this.read_type(),e=this.is_reference(),f=this.is_variadic();return this.expect(this.tok.T_VARIABLE)&&(b=this.text(),this.next()),"="==this.token&&(c=this.next().read_expr()),a(b,d,c,e,f)},read_function_argument_list:function(){var a=[];if(this.expect("(")&&this.next(),")"!==this.token)for(;this.token!=this.EOF&&(a.push(this.read_argument_list()),","===this.token);)this.next();return this.expect(")")&&this.next(),a},read_argument_list:function(){return this.token===this.tok.T_ELLIPSIS?this.node("variadic")(this.next().read_expr()):this.read_expr(); +},read_type:function(){switch(this.token){case this.tok.T_ARRAY:return this.next(),["array"];case this.tok.T_NS_SEPARATOR:case this.tok.T_STRING:return this.read_namespace_name();case this.tok.T_CALLABLE:return this.next(),["callable"];default:return null}}}},{}],80:[function(a,b,c){b.exports={read_if:function(){var a=this.node("if"),b=null,c=null,d=!1,e=null;if(e=this.read_if_expr(),":"===this.token){d=!0,this.next(),b=this.node("block");for(var f=[];this.token!=this.EOF&&this.token!==this.tok.T_ENDIF;){if(this.ignoreComments(),this.token===this.tok.T_ELSEIF){c=this.next().read_elseif_short();break}if(this.token===this.tok.T_ELSE){c=this.next().read_else_short();break}f.push(this.read_inner_statement())}b=b(null,f),this.ignoreComments().expect(this.tok.T_ENDIF)&&this.next(),this.expectEndOfStatement()}else b=this.read_statement(),this.ignoreComments(),this.token===this.tok.T_ELSEIF?c=this.next().read_if():this.token===this.tok.T_ELSE&&(c=this.next().read_statement());return a(e,b,c,d)},read_if_expr:function(){ +this.expect("(")&&this.next();var a=this.read_expr();return this.expect(")")&&this.next(),a},read_elseif_short:function(){var a=this.node("if"),b=null,c=null,d=null,e=[];for(c=this.read_if_expr(),this.expect(":")&&this.next(),d=this.node("block");this.token!=this.EOF&&this.token!==this.tok.T_ENDIF;){if(this.token===this.tok.T_ELSEIF){b=this.next().read_elseif_short();break}if(this.token===this.tok.T_ELSE){b=this.next().read_else_short();break}e.push(this.read_inner_statement())}return d=d(null,e),a(c,d,b,!0)},read_else_short:function(){this.expect(":")&&this.next();for(var a=this.node("block"),b=[];this.token!=this.EOF&&this.token!==this.tok.T_ENDIF;)b.push(this.read_inner_statement());return a(null,b)}}},{}],81:[function(a,b,c){"use strict";b.exports={read_while:function(){var a=this.node("while"),b=null,c=null,d=!1;return this.expect("(")&&this.next(),b=this.read_expr(),this.expect(")")&&this.next(),":"===this.token?(d=!0,c=this.read_short_form(this.tok.T_ENDWHILE)):c=this.read_statement(),a(b,c,d)},read_do:function(){ +var a=this.node("do"),b=null,c=null;return c=this.read_statement(),this.expect(this.tok.T_WHILE)&&(this.next().expect("(")&&this.next(),b=this.read_expr(),this.expect(")")&&this.next(),this.expect(";")&&this.next()),a(b,c)},read_for:function(){var a=this.node("for"),b=[],c=[],d=[],e=null,f=!1;return this.expect("(")&&this.next(),";"!==this.token?(b=this.read_list(this.read_expr,","),this.expect(";")&&this.next()):this.next(),";"!==this.token?(c=this.read_list(this.read_expr,","),this.expect(";")&&this.next()):this.next(),")"!==this.token?(d=this.read_list(this.read_expr,","),this.expect(")")&&this.next()):this.next(),":"===this.token?(f=!0,e=this.read_short_form(this.tok.T_ENDFOR)):e=this.read_statement(),a(b,c,d,e,f)},read_foreach:function(){var a=this.node("foreach"),b=null,c=null,d=null,e=null,f=!1;return this.expect("(")&&this.next(),b=this.read_expr(),this.expect(this.tok.T_AS)&&(this.next(),d=this.read_foreach_variable(),this.token===this.tok.T_DOUBLE_ARROW&&(c=d,d=this.next().read_foreach_variable())),this.expect(")")&&this.next(), +":"===this.token?(f=!0,e=this.read_short_form(this.tok.T_ENDFOREACH)):e=this.read_statement(),a(b,c,d,e,f)},read_foreach_variable:function(){if(this.token===this.tok.T_LIST){var a=this.node("list");this.next().expect("(")&&this.next();var b=this.read_assignment_list();return this.expect(")")&&this.next(),a(b)}return"["===this.token?this.read_array():this.read_variable(!1,!1,!1)}}},{}],82:[function(a,b,c){b.exports={read_start:function(){return this.token==this.tok.T_NAMESPACE?this.read_namespace():this.read_top_statement()}}},{}],83:[function(a,b,c){b.exports={read_namespace:function(){this.expect(this.tok.T_NAMESPACE)&&this.next();var a=this.node("namespace");if("{"==this.token)return this.currentNamespace=[""],a([""],this.read_code_block(!0));this.token===this.tok.T_NAMESPACE&&(this.error(["{",this.tok.T_STRING]),this.next());var b=this.read_namespace_name();if(";"==this.token){this.currentNamespace=b;var c=this.nextWithComments().read_top_statements();return this.expect(this.EOF),a(b,c)}if("{"==this.token)return this.currentNamespace=b, +a(b,this.read_code_block(!0));if("("===this.token)return this.node("call")(["ns",b.slice(1)],this.read_function_argument_list());this.error(["{",";"]),this.currentNamespace=b;var c=this.read_top_statements();return this.expect(this.EOF),a(b,c)},read_namespace_name:function(){var a=this.node("identifier");return this.token===this.tok.T_NAMESPACE&&this.next().expect(this.tok.T_NS_SEPARATOR)&&this.next(),a(this.read_list(this.tok.T_STRING,this.tok.T_NS_SEPARATOR,!0))},read_use_statements:function(){for(var a=[];this.token!==this.EOF&&(this.expect(this.tok.T_USE)&&this.next().read_list(this.read_use_statement_mixed,",").forEach(function(b){Array.isArray(b)?a=a.concat(b):a.push(b)}),this.token===this.tok.T_USE););return a},read_inline_use_declaration:function(a){for(var b=[];this.token!==this.EOF;){var c=this.node("use"),d=this.read_use_statement(a[3]!==!1);if(this.token===this.tok.T_AS&&(this.next().expect(this.tok.T_STRING),d[1]=this.text(),this.next()),d[0]=a[0].concat(d[0]),a[2]!==!1&&(d[2]=a[2]),b.push(c.apply(this,d)), +","!==this.token)break;this.next()}return b},read_use_statement_mixed:function(){var a=this.node("use"),b=this.read_use_statement();if(this.token===this.tok.T_AS)this.next().expect(this.tok.T_STRING)&&(b[1]=this.text(),this.next());else if("{"===this.token)return b=this.next().read_inline_use_declaration(b),this.expect("}")&&this.next(),b;return a.apply(this,b)},read_use_statement:function(a){var b=!1;a||this.token!==this.tok.T_FUNCTION&&this.token!==this.tok.T_CONST||(b=this.token===this.tok.T_FUNCTION?"function":"constant",this.next());var c=this.read_namespace_name();return[c,c[c.length-1],b]}}},{}],84:[function(a,b,c){var d={"\\r":"\r","\\n":"\n","\\t":"\t","\\v":String.fromCharCode(11),"\\e":String.fromCharCode(27),"\\f":String.fromCharCode(12),"\\\\":"\\","\\$":"$",'\\"':'"',"\\'":"'"};b.exports={resolve_special_chars:function(a){return a.replace(/\\[rntvef"'\\\$]/g,function(a){return d[a]})},read_scalar:function(){if(this.is("T_MAGIC_CONST"))return this.get_magic_constant();switch(this.token){case this.tok.T_CONSTANT_ENCAPSED_STRING: +var a=this.node("string"),b=this.text(),c=!1,d="b"===a[0]||"B"===a[0];return d?(c='"'===b[1],b=b.substring(2,b.length-1)):(c='"'===b[0],b=b.substring(1,b.length-1)),a=a(c,this.resolve_special_chars(b)),d&&(a=["cast","binary",a]),this.next(),this.token===this.tok.T_DOUBLE_COLON?this.read_static_getter(a):a;case this.tok.T_START_HEREDOC:return this.next().read_encapsed_string(this.tok.T_END_HEREDOC);case'"':return this.next().read_encapsed_string('"');case'b"':case'B"':return["cast","binary",this.next().read_encapsed_string('"')];case"-":case this.tok.T_LNUMBER:case this.tok.T_DNUMBER:var e=this.node("number"),a=this.text();return"-"===this.token&&(this.next().expect([this.tok.T_LNUMBER,this.tok.T_DNUMBER]),a+=this.text()),e=e(a),this.next(),e;case this.tok.T_NAMESPACE:case this.tok.T_NS_SEPARATOR:case this.tok.T_STRING:var a=this.read_namespace_name(),e=["constant",a];for(this.token==this.tok.T_DOUBLE_COLON&&this.next().expect([this.tok.T_STRING,this.tok.T_CLASS])&&(e[1]=[a,this.text()],this.next());"["===this.token;)e=["offset",e,this.next().read_expr()], +this.expect("]")&&this.next();return e;case this.tok.T_ARRAY:case"[":return this.read_array();default:var f=this.error("SCALAR");return this.next(),f}},read_dereferencable:function(a){var b;return"["===this.token?(b=["offset",a,this.next().read_expr()],this.expect("]")&&this.next()):this.token===this.tok.T_DOLLAR_OPEN_CURLY_BRACES&&(b=["offset",a,this.read_encapsed_string_item()]),b},read_encapsed_string_item:function(){var a=null;return this.token===this.tok.T_ENCAPSED_AND_WHITESPACE?(a=this.node("string")(!1,this.text()),this.next()):this.token===this.tok.T_DOLLAR_OPEN_CURLY_BRACES?(this.next().token===this.tok.T_STRING_VARNAME?(a=["var",this.text()],"["===this.next().token&&(a=["offset",a,this.next().read_expr()],this.expect("]")&&this.next())):a=this.read_expr(),this.expect("}")&&this.next()):this.token===this.tok.T_CURLY_OPEN?(a=this.next().read_variable(!1,!1,!1),this.expect("}")&&this.next()):"["===this.token?(a=["offset",a,this.next().read_expr()],this.expect("]")&&this.next()):this.token===this.tok.T_VARIABLE?a=this.read_variable(!1,!0,!1):this.expect([this.tok.T_VARIABLE,this.tok.T_CURLY_OPEN,this.tok.T_DOLLAR_OPEN_CURLY_BRACES,this.tok.T_ENCAPSED_AND_WHITESPACE]), +a},read_encapsed_string:function(a){if(this.token===a)return this.next(),null;var b=this.read_encapsed_string_item();if(this.token===a)return this.next(),b;for(var c=["bin",".",b,this.read_encapsed_string_item()];this.token!==a;)c[3]=["bin",".",c[3],this.read_encapsed_string_item()];return this.expect(a)&&this.next(),c},get_magic_constant:function(){var a=this.node("magic"),b=this.text();return this.next(),a(b)}}},{}],85:[function(a,b,c){b.exports={read_top_statements:function(){for(var a=[];this.token!==this.EOF&&"}"!==this.token;){var b=this.read_top_statement();b&&(Array.isArray(b)?a=a.concat(b):a.push(b))}return a},read_top_statement:function(){switch(this.token){case this.tok.T_FUNCTION:return this.read_function(!1,!1);case this.tok.T_ABSTRACT:case this.tok.T_FINAL:var a=this.read_class_scope();return this.token===this.tok.T_CLASS?this.read_class(a):(this.error(this.tok.T_CLASS),this.next(),null);case this.tok.T_CLASS:return this.read_class([0,0,0]);case this.tok.T_INTERFACE:return this.read_interface();case this.tok.T_TRAIT: +return this.read_trait();case this.tok.T_USE:var b=this.read_use_statements();return this.expect(";")&&this.nextWithComments(),b;case this.tok.T_CONST:return this.next().read_const_list();case this.tok.T_NAMESPACE:return this.read_namespace();case this.tok.T_HALT_COMPILER:var c=this.node("halt");return this.next().expect("(")&&this.next(),this.expect(")")&&this.next(),this.expect(";"),this.lexer.done=!0,c(this.lexer._input.substring(this.lexer.offset));default:return this.read_statement()}},read_inner_statements:function(){for(var a=[];this.token!=this.EOF&&"}"!==this.token;){var b=this.read_inner_statement();b&&(Array.isArray(b)?a=a.concat(b):a.push(b))}return a},read_const_list:function(){var a=this.read_list(function(){this.expect(this.tok.T_STRING);var a=this.node("constant"),b=this.text();return this.next().expect("=")?a(b,this.next().read_expr()):a(b,null)},",",!1);return this.expectEndOfStatement(),a},read_declare_list:function(){return this.read_list(function(){this.expect(this.tok.T_STRING);var a=this.text(); +return this.next().expect("=")?[a,this.next().read_expr()]:[a,null]},",")},read_inner_statement:function(){switch(this.token){case this.tok.T_FUNCTION:return this.read_function(!1,!1);case this.tok.T_ABSTRACT:case this.tok.T_FINAL:var a=this.read_class_scope();return this.token===this.tok.T_CLASS?this.read_class(a):(this.error(this.tok.T_CLASS),this.next(),null);case this.tok.T_CLASS:return this.read_class([0,0,0]);case this.tok.T_INTERFACE:return this.read_interface();case this.tok.T_TRAIT:return this.read_trait();case this.tok.T_HALT_COMPILER:this.next().expect("(")&&this.next(),this.expect(")")&&this.next(),this.expect(";")&&this.next(),this.raiseError("__HALT_COMPILER() can only be used from the outermost scope");default:return this.read_statement()}},read_statement:function(){switch(this.token){case"{":return this.read_code_block(!1);case this.tok.T_IF:return this.next().read_if();case this.tok.T_SWITCH:return this.read_switch();case this.tok.T_FOR:return this.next().read_for();case this.tok.T_FOREACH:return this.next().read_foreach(); +case this.tok.T_WHILE:return this.next().read_while();case this.tok.T_DO:return this.next().read_do();case this.tok.T_COMMENT:return this.read_comment();case this.tok.T_DOC_COMMENT:return this.read_doc_comment();case this.tok.T_RETURN:var a=this.node("return"),b=null;return this.next().is("EOS")||(b=this.read_expr()),this.expectEndOfStatement(),a(b);case this.tok.T_BREAK:var a=this.node("break");return this.next().expectEndOfStatement(),a();case this.tok.T_CONTINUE:var a=this.node("continue");return this.next().expectEndOfStatement(),a();case this.tok.T_GLOBAL:var c=this.next().read_list(this.read_simple_variable,",");return this.expectEndOfStatement(),["global",c];case this.tok.T_STATIC:var d=[this.token,this.lexer.getState()],a=this.node("static");if(this.next().token===this.tok.T_DOUBLE_COLON){this.lexer.tokens.push(d);var b=this.next().read_expr();return this.expect(";")&&this.nextWithComments(),b}var c=this.read_list(function(){var a=null,b=null;return this.expect(this.tok.T_VARIABLE)&&(b=this.text(),this.next()), +"="===this.token&&(a=this.next().read_expr()),[b,a]},",");return this.expectEndOfStatement(),a("declare",c);case this.tok.T_ECHO:var a=this.node("echo"),e="("===this.next().token;e&&this.next();var f=this.read_list(this.read_expr,",");return e&&this.expect(")")&&this.next(),this.expectEndOfStatement(),a(f);case this.tok.T_INLINE_HTML:var a=this.node("inline")(this.text());return this.next(),a;case this.tok.T_UNSET:var a=this.node("unset");this.next().expect("(")&&this.next();var c=this.read_list(this.read_variable,",");return this.expect(")")&&this.next(),this.expect(";")&&this.nextWithComments(),a(c);case this.tok.T_DECLARE:var g,h,a=this.node("declare");if(this.next().expect("(")&&this.next(),g=this.read_declare_list(),this.expect(")")&&this.nextWithComments(),":"===this.token){for(h=[],this.next();this.token!=this.EOF&&this.token!==this.tok.T_ENDDECLARE;)h.push(this.read_statement());this.ignoreComments().expect(this.tok.T_ENDDECLARE)&&this.next(),this.expectEndOfStatement()}else h=this.read_statement();return a(g,h); +case this.tok.T_TRY:return this.read_try();case this.tok.T_THROW:var a=this.node("throw"),b=this.next().read_expr();return this.expectEndOfStatement(),a(b);case";":case this.tok.T_CLOSE_TAG:return this.next(),null;case this.tok.T_STRING:var d=[this.token,this.lexer.getState()],i=this.text();if(":"===this.next().token){var a=this.node("label");return this.next(),a(i)}this.lexer.tokens.push(d);var b=this.next().read_expr();return this.expect([";",this.tok.T_CLOSE_TAG])&&this.nextWithComments(),b;case this.tok.T_GOTO:var a=this.node("goto"),i=null;return this.next().expect(this.tok.T_STRING)&&(i=this.text(),this.next().expectEndOfStatement()),a(i);default:var b=this.read_expr();return this.expectEndOfStatement(),b}},read_code_block:function(a){var b=this.node("block");this.expect("{")&&this.nextWithComments();var c=a?this.read_top_statements():this.read_inner_statements();return this.expect("}")&&this.nextWithComments(),b(null,c)}}},{}],86:[function(a,b,c){"use strict";b.exports={read_switch:function(){this.expect(this.tok.T_SWITCH)&&this.next(); +var a,b,c,d=this.node("switch");return this.expect("(")&&this.next(),a=this.read_expr(),this.expect(")")&&this.next(),c=":"===this.token,b=this.read_switch_case_list(),d(a,b,c)},read_switch_case_list:function(){var a=null,b=this.node("block"),c=[];for("{"===this.token?a="}":":"===this.token?a=this.tok.T_ENDSWITCH:this.expect(["{",":"]),";"===this.next().token&&this.next(),this.token===this.tok.T_CLOSE_TAG&&this.next();this.token!==this.EOF&&this.token!==a;)c.push(this.read_case_list(a));return this.expect(a)&&this.next(),a===this.tok.T_ENDSWITCH&&this.expectEndOfStatement(),b(null,c)},read_case_list:function(a){var b=this.node("case"),c=null,d=null,e=[];for(this.token===this.tok.T_CASE?c=this.next().read_expr():this.token===this.tok.T_DEFAULT?this.next():this.expect([this.tok.T_CASE,this.tok.T_DEFAULT]),this.expect([":",";"])&&this.next(),d=this.node("block");this.token!=this.EOF&&this.token!==a&&this.token!==this.tok.T_CASE&&this.token!==this.tok.T_DEFAULT;)e.push(this.read_inner_statement());return b(c,e.length>0?d(null,e):null); +}}},{}],87:[function(a,b,c){b.exports={read_try:function(){this.expect(this.tok.T_TRY);var a=this.node("try"),b=this.nextWithComments().read_statement(),c=!1,d=[];for(this.ignoreComments();this.token===this.tok.T_CATCH;){this.next().expect("(")&&this.next();var e=this.read_namespace_name(),f=this.read_variable(!0,!1,!1);this.expect(")")&&this.nextWithComments(),d.push({exception:e,as:f,body:this.read_statement()}),this.ignoreComments()}return this.token===this.tok.T_FINALLY&&(c=this.nextWithComments().read_statement()),a(b,d,c)}}},{}],88:[function(a,b,c){"use strict";b.exports={read_short_form:function(a){var b=this.node("block"),c=[];for(this.expect(":")&&this.next();this.token!=this.EOF&&this.token!==a;)c.push(this.read_inner_statement());return this.expect(a)&&this.next(),this.expectEndOfStatement(),b(null,c)},read_list:function(a,b,c){var d=[];if(this.token==b&&(c&&d.push(""),this.next()),"function"==typeof a){do if(d.push(a.apply(this,[])),this.token!=b)break;while(this.next().token!=this.EOF)}else for(this.expect(a)&&d.push(this.text());this.next().token!=this.EOF&&this.token==b&&this.next().token==a;)d.push(this.text()); +return d},read_name_list:function(){return this.read_list(this.read_namespace_name,",",!1)}}},{}],89:[function(a,b,c){b.exports={read_variable:function(a,b,c){var d;if(c||"&"!==this.token||(c=!0,this.next()),this.is([this.tok.T_VARIABLE,"$"]))d=this.read_reference_variable(b,c);else if(this.is([this.tok.T_NS_SEPARATOR,this.tok.T_STRING])){d=this.node();var e=this.read_namespace_name();if(this.token!=this.tok.T_DOUBLE_COLON&&"("!=this.token){var f=e.name.toLowerCase();d="true"===f?d("boolean",!0):"false"===f?d("boolean",!1):d("constref",e)}else d=e}else this.token===this.tok.T_STATIC?(this.next(),d=["ns",["static"]]):this.expect("VARIABLE");return this.token===this.tok.T_DOUBLE_COLON&&(d=this.read_static_getter(d,b)),this.recursive_variable_chain_scan(d,a,b)},read_static_getter:function(a,b){var c=null;return this.next().is([this.tok.T_VARIABLE,"$"])?c=this.read_reference_variable(b,!1):this.token===this.tok.T_STRING||this.token===this.tok.T_CLASS?(c=this.text(),this.next()):(c=this.error([this.tok.T_VARIABLE,this.tok.T_STRING]), +this.next()),"ns"!=a[0]&&(a=["lookup","class",a]),["static","get",a,c]},recursive_variable_chain_scan:function(a,b,c){a:for(;this.token!=this.EOF;)switch(this.token){case"(":if(b)return a;a=["call",a,this.read_function_argument_list()];break;case"[":this.next();var d=!1;c?(d=this.read_encaps_var_offset(),this.expect("]")&&this.next()):"]"!==this.token?(d=this.read_expr(),this.expect("]")&&this.next()):this.next(),a=["offset",a,d];break;case this.tok.T_OBJECT_OPERATOR:var e;switch(this.next().token){case this.tok.T_STRING:e=["string",this.text()];var f=this.next().token;f===this.tok.T_VARIABLE?e=["bin",".",e,["var",this.text()]]:"{"===f&&(e=["bin",".",e,this.next().read_expr()],this.expect("}")&&this.next());break;case this.tok.T_VARIABLE:e=["var",this.text()],this.next();break;case"$":this.next().expect(["{",this.tok.T_VARIABLE]),"{"===this.token?(e=this.next().read_expr(),this.expect("}")&&this.next()):e=this.read_expr();break;case"{":e=this.next().read_expr(),this.expect("}")&&this.next();break;default:e=this.error([this.tok.T_STRING,this.tok.T_VARIABLE]), +this.next()}a=["prop",a,e];break;default:break a}return a},read_encaps_var_offset:function(){var a=this.node();if(this.token===this.tok.T_STRING){var b=this.text(),c='"'===b[0];b=b.substring(1,b.length-1),a=a("string",c,this.resolve_special_chars(b))}else this.token===this.tok.T_NUM_STRING?a=a("number",this.text()):this.token===this.tok.T_VARIABLE?a=a("variable",this.text()):this.expect([this.tok.T_STRING,this.tok.T_NUM_STRING,this.tok.T_VARIABLE]);return this.next(),a},read_reference_variable:function(a,b){for(var c=this.read_simple_variable(b);this.token!=this.EOF;)if("["==this.token){if(a)c=this.next().read_encaps_var_offset();else{var d="]"===this.next().token?null:this.read_dim_offset();c=["offset",c,d]}this.expect("]")&&this.next()}else{if("{"!=this.token||a)break;c=["offset",c,this.next().read_expr()],this.expect("}")&&this.next()}return c},read_simple_variable:function(a){var b=this.node("variable");if(this.expect([this.tok.T_VARIABLE,"$"])&&this.token===this.tok.T_VARIABLE)b=b(this.text(),a),this.next();else{ +switch("$"===this.token&&this.next(),this.token){case"{":b=this.next().read_expr(),this.expect("}")&&this.next();break;case"$":b=["lookup","var",this.read_simple_variable(!1)];break;case this.tok.T_VARIABLE:b=["var",this.text()],this.next();break;default:b=this.error(["{","$",this.tok.T_VARIABLE]),this.next()}b=["lookup","var",b]}return b}}},{}],90:[function(a,b,c){b.exports={values:{101:"T_HALT_COMPILER",102:"T_USE",103:"T_ENCAPSED_AND_WHITESPACE",104:"T_OBJECT_OPERATOR",105:"T_STRING",106:"T_DOLLAR_OPEN_CURLY_BRACES",107:"T_STRING_VARNAME",108:"T_CURLY_OPEN",109:"T_NUM_STRING",110:"T_ISSET",111:"T_EMPTY",112:"T_INCLUDE",113:"T_INCLUDE_ONCE",114:"T_EVAL",115:"T_REQUIRE",116:"T_REQUIRE_ONCE",117:"T_NAMESPACE",118:"T_NS_SEPARATOR",119:"T_AS",120:"T_IF",121:"T_ENDIF",122:"T_WHILE",123:"T_DO",124:"T_FOR",125:"T_SWITCH",126:"T_BREAK",127:"T_CONTINUE",128:"T_RETURN",129:"T_GLOBAL",130:"T_STATIC",131:"T_ECHO",132:"T_INLINE_HTML",133:"T_UNSET",134:"T_FOREACH",135:"T_DECLARE",136:"T_TRY",137:"T_THROW",138:"T_GOTO",139:"T_FINALLY", 140:"T_CATCH",141:"T_ENDDECLARE",142:"T_LIST",143:"T_CLONE",144:"T_PLUS_EQUAL",145:"T_MINUS_EQUAL",146:"T_MUL_EQUAL",147:"T_DIV_EQUAL",148:"T_CONCAT_EQUAL",149:"T_MOD_EQUAL",150:"T_AND_EQUAL",151:"T_OR_EQUAL",152:"T_XOR_EQUAL",153:"T_SL_EQUAL",154:"T_SR_EQUAL",155:"T_INC",156:"T_DEC",157:"T_BOOLEAN_OR",158:"T_BOOLEAN_AND",159:"T_LOGICAL_OR",160:"T_LOGICAL_AND",161:"T_LOGICAL_XOR",162:"T_SL",163:"T_SR",164:"T_IS_IDENTICAL",165:"T_IS_NOT_IDENTICAL",166:"T_IS_EQUAL",167:"T_IS_NOT_EQUAL",168:"T_IS_SMALLER_OR_EQUAL",169:"T_IS_GREATER_OR_EQUAL",170:"T_INSTANCEOF",171:"T_INT_CAST",172:"T_DOUBLE_CAST",173:"T_STRING_CAST",174:"T_ARRAY_CAST",175:"T_OBJECT_CAST",176:"T_BOOL_CAST",177:"T_UNSET_CAST",178:"T_EXIT",179:"T_PRINT",180:"T_YIELD",181:"T_YIELD_FROM",182:"T_FUNCTION",183:"T_DOUBLE_ARROW",184:"T_DOUBLE_COLON",185:"T_ARRAY",186:"T_CALLABLE",187:"T_CLASS",188:"T_ABSTRACT",189:"T_TRAIT",190:"T_FINAL",191:"T_EXTENDS",192:"T_INTERFACE",193:"T_IMPLEMENTS",194:"T_VAR",195:"T_PUBLIC",196:"T_PROTECTED",197:"T_PRIVATE",198:"T_CONST", 199:"T_NEW",200:"T_INSTEADOF",201:"T_ELSEIF",202:"T_ELSE",203:"T_ENDSWITCH",204:"T_CASE",205:"T_DEFAULT",206:"T_ENDFOR",207:"T_ENDFOREACH",208:"T_ENDWHILE",209:"T_CONSTANT_ENCAPSED_STRING",210:"T_LNUMBER",211:"T_DNUMBER",212:"T_LINE",213:"T_FILE",214:"T_DIR",215:"T_TRAIT_C",216:"T_METHOD_C",217:"T_FUNC_C",218:"T_NS_C",219:"T_START_HEREDOC",220:"T_END_HEREDOC",221:"T_CLASS_C",222:"T_VARIABLE",223:"T_OPEN_TAG",224:"T_OPEN_TAG_WITH_ECHO",225:"T_CLOSE_TAG",226:"T_WHITESPACE",227:"T_COMMENT",228:"T_DOC_COMMENT",229:"T_ELLIPSIS",230:"T_COALESCE",231:"T_POW",232:"T_POW_EQUAL",233:"T_SPACESHIP"},names:{T_HALT_COMPILER:101,T_USE:102,T_ENCAPSED_AND_WHITESPACE:103,T_OBJECT_OPERATOR:104,T_STRING:105,T_DOLLAR_OPEN_CURLY_BRACES:106,T_STRING_VARNAME:107,T_CURLY_OPEN:108,T_NUM_STRING:109,T_ISSET:110,T_EMPTY:111,T_INCLUDE:112,T_INCLUDE_ONCE:113,T_EVAL:114,T_REQUIRE:115,T_REQUIRE_ONCE:116,T_NAMESPACE:117,T_NS_SEPARATOR:118,T_AS:119,T_IF:120,T_ENDIF:121,T_WHILE:122,T_DO:123,T_FOR:124,T_SWITCH:125,T_BREAK:126,T_CONTINUE:127,T_RETURN:128, T_GLOBAL:129,T_STATIC:130,T_ECHO:131,T_INLINE_HTML:132,T_UNSET:133,T_FOREACH:134,T_DECLARE:135,T_TRY:136,T_THROW:137,T_GOTO:138,T_FINALLY:139,T_CATCH:140,T_ENDDECLARE:141,T_LIST:142,T_CLONE:143,T_PLUS_EQUAL:144,T_MINUS_EQUAL:145,T_MUL_EQUAL:146,T_DIV_EQUAL:147,T_CONCAT_EQUAL:148,T_MOD_EQUAL:149,T_AND_EQUAL:150,T_OR_EQUAL:151,T_XOR_EQUAL:152,T_SL_EQUAL:153,T_SR_EQUAL:154,T_INC:155,T_DEC:156,T_BOOLEAN_OR:157,T_BOOLEAN_AND:158,T_LOGICAL_OR:159,T_LOGICAL_AND:160,T_LOGICAL_XOR:161,T_SL:162,T_SR:163,T_IS_IDENTICAL:164,T_IS_NOT_IDENTICAL:165,T_IS_EQUAL:166,T_IS_NOT_EQUAL:167,T_IS_SMALLER_OR_EQUAL:168,T_IS_GREATER_OR_EQUAL:169,T_INSTANCEOF:170,T_INT_CAST:171,T_DOUBLE_CAST:172,T_STRING_CAST:173,T_ARRAY_CAST:174,T_OBJECT_CAST:175,T_BOOL_CAST:176,T_UNSET_CAST:177,T_EXIT:178,T_PRINT:179,T_YIELD:180,T_YIELD_FROM:181,T_FUNCTION:182,T_DOUBLE_ARROW:183,T_DOUBLE_COLON:184,T_ARRAY:185,T_CALLABLE:186,T_CLASS:187,T_ABSTRACT:188,T_TRAIT:189,T_FINAL:190,T_EXTENDS:191,T_INTERFACE:192,T_IMPLEMENTS:193,T_VAR:194,T_PUBLIC:195,T_PROTECTED:196, T_PRIVATE:197,T_CONST:198,T_NEW:199,T_INSTEADOF:200,T_ELSEIF:201,T_ELSE:202,T_ENDSWITCH:203,T_CASE:204,T_DEFAULT:205,T_ENDFOR:206,T_ENDFOREACH:207,T_ENDWHILE:208,T_CONSTANT_ENCAPSED_STRING:209,T_LNUMBER:210,T_DNUMBER:211,T_LINE:212,T_FILE:213,T_DIR:214,T_TRAIT_C:215,T_METHOD_C:216,T_FUNC_C:217,T_NS_C:218,T_START_HEREDOC:219,T_END_HEREDOC:220,T_CLASS_C:221,T_VARIABLE:222,T_OPEN_TAG:223,T_OPEN_TAG_WITH_ECHO:224,T_CLOSE_TAG:225,T_WHITESPACE:226,T_COMMENT:227,T_DOC_COMMENT:228,T_ELLIPSIS:229,T_COALESCE:230,T_POW:231,T_POW_EQUAL:232,T_SPACESHIP:233}}},{}],"php-parser":[function(a,b,c){function d(a,b){for(var c=Object.keys(a),e=c.length;e--;){var f=c[e],g=a[f];null===g?delete b[f]:"function"==typeof g?b[f]=g.bind(b):Array.isArray(g)?b[f]=Array.isArray(b[f])?b[f].concat(g):g:"object"==typeof g?b[f]="object"==typeof b[f]?d(g,b[f]):g:b[f]=g}return b}var e=a("./lexer"),f=a("./parser"),g=a("./tokens"),h=a("./ast"),i=function(a){return"function"==typeof this?new this(a):(this.tokens=g,this.lexer=new e(this),this.ast=new h, -this.parser=new f(this.lexer,this.ast),void(a&&"object"==typeof a&&d(a,this)))};i.create=function(a){return new i(a)},i.parseEval=function(a,b){var c=new i(b);return c.parseEval(a)},i.prototype.parseEval=function(a){return this.lexer.mode_eval=!0,this.lexer.all_tokens=!1,this.parser.parse(a)},i.parseCode=function(a,b){var c=new i(b);return c.parseCode(a)},i.prototype.parseCode=function(a){return this.lexer.mode_eval=!1,this.lexer.all_tokens=!1,this.parser.parse(a)},i.tokenGetAll=function(a,b){var c=new i(b);return c.tokenGetAll(a)},i.prototype.tokenGetAll=function(a){this.lexer.mode_eval=!1,this.lexer.all_tokens=!0;var b=this.lexer.EOF,c=this.tokens.values;this.lexer.setInput(a);for(var d=this.lexer.lex()||b,e=[];d!=b;){var f=this.lexer.yytext;c.hasOwnProperty(d)&&(f=[c[d],f,this.lexer.yylloc.first_line]),e.push(f),d=this.lexer.lex()||b}return e},b.exports=i},{"./ast":2,"./lexer":40,"./parser":49,"./tokens":64}]},{},[]); +this.parser=new f(this.lexer,this.ast),void(a&&"object"==typeof a&&d(a,this)))};i.create=function(a){return new i(a)},i.parseEval=function(a,b){var c=new i(b);return c.parseEval(a)},i.prototype.parseEval=function(a){return this.lexer.mode_eval=!0,this.lexer.all_tokens=!1,this.parser.parse(a)},i.parseCode=function(a,b){var c=new i(b);return c.parseCode(a)},i.prototype.parseCode=function(a){return this.lexer.mode_eval=!1,this.lexer.all_tokens=!1,this.parser.parse(a)},i.tokenGetAll=function(a,b){var c=new i(b);return c.tokenGetAll(a)},i.prototype.tokenGetAll=function(a){this.lexer.mode_eval=!1,this.lexer.all_tokens=!0;var b=this.lexer.EOF,c=this.tokens.values;this.lexer.setInput(a);for(var d=this.lexer.lex()||b,e=[];d!=b;){var f=this.lexer.yytext;c.hasOwnProperty(d)&&(f=[c[d],f,this.lexer.yylloc.first_line]),e.push(f),d=this.lexer.lex()||b}return e},b.exports=i},{"./ast":2,"./lexer":65,"./parser":74,"./tokens":90}]},{},[]); //# sourceMappingURL=php-parser.min.js.map \ No newline at end of file diff --git a/dist/php-parser.min.js.map b/dist/php-parser.min.js.map index 9c9ec7b95..f77f985e8 100644 --- a/dist/php-parser.min.js.map +++ b/dist/php-parser.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["php-parser.js"],"names":["require","e","t","n","r","s","o","u","a","i","f","Error","code","l","exports","call","length","1","module","defaultSetTimout","defaultClearTimeout","runTimeout","fun","cachedSetTimeout","setTimeout","this","runClearTimeout","marker","cachedClearTimeout","clearTimeout","cleanUpNextTick","draining","currentQueue","queue","concat","queueIndex","drainQueue","timeout","len","run","Item","array","noop","process","nextTick","args","Array","arguments","push","prototype","apply","title","browser","env","argv","version","versions","on","addListener","once","off","removeListener","removeAllListeners","emit","binding","name","cwd","chdir","dir","umask","2","Location","Position","AST","withPositions","withSource","prepare","kind","parser","start","lexer","yylloc","first_line","first_column","first_offset","self","location","slice","src","_input","substring","offset","shift","node","result","Object","create","forEach","ctor","constructor","toLowerCase","./ast/array","./ast/assign","./ast/boolean","./ast/class","./ast/classconstant","./ast/clone","./ast/coalesce","./ast/constant","./ast/echo","./ast/empty","./ast/entry","./ast/error","./ast/eval","./ast/exit","./ast/include","./ast/inline","./ast/isset","./ast/literal","./ast/location","./ast/magic","./ast/method","./ast/namespace","./ast/number","./ast/position","./ast/print","./ast/program","./ast/shell","./ast/string","./ast/unset","./ast/variable","3","Expr","KIND","extends","shortForm","items","./expression","4","Statement","Assign","left","right","operator","./statement","5","Block","children","6","Literal","Boolean","value","./literal","7","Class","isFinal","isAbstract","ext","impl","isAnonymous","implements","./block","8","Constant","ClassConstant","flags","type","parseFlags","./constant","9","Clone","what","10","Coalesce","test","ifnull","11","Declaration","./declaration","12","13","Sys","Echo","./sys","14","Empty","15","Node","Entry","key","./node","16","message","token","line","expected","17","Eval","source","18","Exit","status","19","Expression","20","Identifier","fqn","isArray","join","21","Include","target","22","Inline","23","Isset","24","25","end","26","Magic","27","Method","28","Namespace","withBrackets","./identifier","29","loc","30","_Number","31","column","32","Print","33","Program","errors","34","Shell","35","36","String","isDoubleQuote","37","38","Unset","39","Variable","identifier","byref","40","engine","tok","tokens","names","EOF","all_tokens","comment_tokens","mode_eval","asp_tags","short_tags","yyprevcol","keywords","__class__","T_CLASS_C","__trait__","T_TRAIT_C","__function__","T_FUNC_C","__method__","T_METHOD_C","__line__","T_LINE","__file__","T_FILE","__dir__","T_DIR","__namespace__","T_NS_C","exit","T_EXIT","die","function","T_FUNCTION","const","T_CONST","return","T_RETURN","try","T_TRY","catch","T_CATCH","finally","T_FINALLY","throw","T_THROW","if","T_IF","elseif","T_ELSEIF","endif","T_ENDIF","else","T_ELSE","while","T_WHILE","endwhile","T_ENDWHILE","do","T_DO","for","T_FOR","endfor","T_ENDFOR","foreach","T_FOREACH","endforeach","T_ENDFOREACH","declare","T_DECLARE","enddeclare","T_ENDDECLARE","instanceof","T_INSTANCEOF","as","T_AS","switch","T_SWITCH","endswitch","T_ENDSWITCH","case","T_CASE","default","T_DEFAULT","break","T_BREAK","continue","T_CONTINUE","goto","T_GOTO","echo","T_ECHO","print","T_PRINT","class","T_CLASS","interface","T_INTERFACE","trait","T_TRAIT","T_EXTENDS","T_IMPLEMENTS","new","T_NEW","clone","T_CLONE","var","T_VAR","eval","T_EVAL","include","T_INCLUDE","include_once","T_INCLUDE_ONCE","T_REQUIRE","require_once","T_REQUIRE_ONCE","namespace","T_NAMESPACE","use","T_USE","insteadof","T_INSTEADOF","global","T_GLOBAL","isset","T_ISSET","empty","T_EMPTY","__halt_compiler","T_HALT_COMPILER","static","T_STATIC","abstract","T_ABSTRACT","final","T_FINAL","private","T_PRIVATE","protected","T_PROTECTED","public","T_PUBLIC","unset","T_UNSET","list","T_LIST","T_ARRAY","callable","T_CALLABLE","or","T_LOGICAL_OR","and","T_LOGICAL_AND","xor","T_LOGICAL_XOR","castKeywords","int","T_INT_CAST","integer","real","T_DOUBLE_CAST","double","float","string","T_STRING_CAST","binary","T_ARRAY_CAST","object","T_OBJECT_CAST","bool","T_BOOL_CAST","boolean","T_UNSET_CAST","setInput","input","size","yylineno","yytext","last_line","last_column","conditionStack","done","begin","ch","unput","last_col","first_col","c","tryMatch","text","ahead","tryMatchCaseless","consume","getState","setState","state","appendToken","lex","next","T_WHITESPACE","T_COMMENT","T_DOC_COMMENT","T_OPEN_TAG","T_OPEN_TAG_WITH_ECHO","condition","curCondition","stateCb","popState","pop","k","./lexer/comments.js","./lexer/initial.js","./lexer/numbers.js","./lexer/property.js","./lexer/scripting.js","./lexer/strings.js","./lexer/tokens.js","./lexer/utils.js","41","aspTagMode","tthis","is_WHITESPACE","42","nextINITIAL","matchINITIAL","T_INLINE_HTML","43","arch","MAX_LENGTH_OF_LONG","long_min_digits","consume_NUM","hasPoint","is_HEX","consume_HNUM","consume_BNUM","is_NUM","consume_LNUM","T_DNUMBER","T_LNUMBER","_process","44","matchST_LOOKING_FOR_PROPERTY","T_OBJECT_OPERATOR","is_LABEL_START","consume_LABEL","T_STRING","matchST_LOOKING_FOR_VARNAME","T_STRING_VARNAME","matchST_VAR_OFFSET","T_NUM_STRING","T_VARIABLE","T_ENCAPSED_AND_WHITESPACE","is_TOKEN","45","matchST_IN_SCRIPTING","consume_TOKEN","T_CONSTANT_ENCAPSED_STRING","ST_DOUBLE_QUOTES","nextCH","T_CLOSE_TAG","46","is_HEREDOC","revert","is_TABSPACE","tChar","yyoffset","is_LABEL","yylabel","heredoc_label","T_START_HEREDOC","prefix","isDOC_MATCH","matchST_NOWDOC","T_END_HEREDOC","matchST_HEREDOC","T_DOLLAR_OPEN_CURLY_BRACES","consume_VARIABLE","T_CURLY_OPEN","matchST_BACKQUOTE","matchST_DOUBLE_QUOTES","47","id","T_YIELD_FROM","T_YIELD","fn","tokenTerminals","$","-","nchar","T_DEC","T_MINUS_EQUAL","\\","T_NS_SEPARATOR","/","T_DIV_EQUAL",":","T_DOUBLE_COLON","(","initial","consume_TABSPACE","yylen","castToken","castId","=","T_DOUBLE_ARROW","T_IS_IDENTICAL","T_IS_EQUAL","+","T_INC","T_PLUS_EQUAL","!","T_IS_NOT_IDENTICAL","T_IS_NOT_EQUAL","?","T_COALESCE","<","T_SL_EQUAL","T_SL","T_SPACESHIP","T_IS_SMALLER_OR_EQUAL",">","T_IS_GREATER_OR_EQUAL","T_SR_EQUAL","T_SR","*","T_MUL_EQUAL","T_POW_EQUAL","T_POW",".","T_CONCAT_EQUAL","T_ELLIPSIS","%","T_MOD_EQUAL","&","T_AND_EQUAL","T_BOOLEAN_AND","|","T_OR_EQUAL","T_BOOLEAN_OR","^","T_XOR_EQUAL","48","charCodeAt","indexOf","is_NEWLINE","49","isNumber","isNaN","parseFloat","isFinite","ast","_gracefulProxy","_graceful","prev","debug","extractDoc","suppressErrors","lastError","startAt","entries","SCALAR","T_MAGIC_CONST","T_MEMBER_FLAGS","VARIABLE","EOS","EXPR","getTokenName","values","parse","_errors","currentNamespace","innerList","program","childs","nextWithComments","read_start","undefined","raiseError","msgExpect","expect","error","msg","symbol","expectEndOfStatement","ignoreStack","showlog","stack","split","trim","found","console","log","ignoreComments","is","read_token","read_list","item","separator","preserveFirstSeparator","./parser/array.js","./parser/class.js","./parser/comment.js","./parser/expr.js","./parser/function.js","./parser/if.js","./parser/loops.js","./parser/main.js","./parser/namespace.js","./parser/scalar.js","./parser/statement.js","./parser/switch.js","./parser/try.js","./parser/variable.js","50","ArrayExpr","ArrayEntry","read_array","read_array_pair_list","read_variable","expr","read_expr","read_dim_offset","51","read_class","flag","propName","propExtends","propImplements","read_namespace_name","read_class_body","read_class_scope","read_member_flags","variables","read_variable_list","variable","locations","read_function","constants","read_constant_list","read_trait_use_statement","read_doc_comment","read_comment","read_variable_declaration","asInterface","idx","val","read_interface","read_interface_body","method","read_function_declaration","comment","read_trait","read_trait_use_alias","origin","act","52","53","read_expr_item","trueArg","recursive_variable_chain_scan","read_dereferencable","read_function_argument_list","read_encapsed_string","isInner","assignList","read_assignment_list","hasItem","read_new_expr","arg","read_scalar","read_class_name_reference","read_static_getter","read_assignment_list_element","54","is_reference","is_variadic","closure","body","read_code_block","nodeName","isRef","returnType","params","read_parameter_list","read_lexical_var","read_type","read_parameter","isVariadic","read_argument_list","55","read_if","cond","read_if_expr","elseCond","read_elseif_short","read_else_short","read_inner_statement","read_statement","56","read_short_form","read_while","read_do","read_for","expr1","expr2","expr3","read_foreach","read_foreach_variable","57","read_namespace","read_top_statement","58","read_top_statements","read_use_statements","read_use_statement_mixed","read_inline_use_declaration","ns","read_use_statement","ignoreType","59","specialChar","\\r","\\n","\\t","\\v","fromCharCode","\\e","\\f","\\\\","\\$","\\\"","\\'","resolve_special_chars","replace","seq","get_magic_constant","isBinCast","err","read_encapsed_string_item","first","60","statement","read_const_list","read_inner_statements","read_declare_list","read_switch","mode","read_simple_variable","current","withParanthesis","options","read_try","label","top","61","cases","read_switch_case_list","read_case_list","stopToken","62","allways","catches","exName","varName","exception","63","read_only","encapsed","read_reference_variable","literal","from","getter","recursive_scan_loop","read_encaps_var_offset","isDblQuote","64","101","102","103","104","105","106","107","108","109","110","111","112","113","114","115","116","117","118","119","120","121","122","123","124","125","126","127","128","129","130","131","132","133","134","135","136","137","138","139","140","141","142","143","144","145","146","147","148","149","150","151","152","153","154","155","156","157","158","159","160","161","162","163","164","165","166","167","168","169","170","171","172","173","174","175","176","177","178","179","180","181","182","183","184","185","186","187","188","189","190","191","192","193","194","195","196","197","198","199","200","201","202","203","204","205","206","207","208","209","210","211","212","213","214","215","216","217","218","219","220","221","222","223","224","225","226","227","228","229","230","231","232","233","php-parser","combine","to","keys","bind","parseEval","buffer","parseCode","tokenGetAll","entry","hasOwnProperty","./ast","./lexer","./parser","./tokens"],"mappings":"AAEAA,QAAQ,QAAUC,GAAEC,EAAEC,EAAEC,GAAG,QAASC,GAAEC,EAAEC,GAAG,IAAIJ,EAAEG,GAAG,CAAC,IAAIJ,EAAEI,GAAG,CAAC,GAAIE,GAAkB,kBAATR,UAAqBA,OAAQ,KAAIO,GAAGC,EAAE,MAAOA,GAAEF,GAAE,EAAI,IAAGG,EAAE,MAAOA,GAAEH,GAAE,EAAI,IAAII,GAAE,GAAIC,OAAM,uBAAuBL,EAAE,IAAK,MAAMI,GAAEE,KAAK,mBAAmBF,EAAE,GAAIG,GAAEV,EAAEG,IAAIQ,WAAYZ,GAAEI,GAAG,GAAGS,KAAKF,EAAEC,QAAQ,SAASb,GAAG,GAAIE,GAAED,EAAEI,GAAG,GAAGL,EAAG,OAAOI,GAAEF,EAAEA,EAAEF,IAAIY,EAAEA,EAAEC,QAAQb,EAAEC,EAAEC,EAAEC,GAAG,MAAOD,GAAEG,GAAGQ,QAAkD,IAAI,GAA1CL,GAAkB,kBAATT,UAAqBA,QAAgBM,EAAE,EAAEA,EAAEF,EAAEY,OAAOV,IAAID,EAAED,EAAEE,GAAI,OAAOD,KAAKY,GAAG,SAASjB,EAAQkB,EAAOJ,GAY/d,QAASK,KACL,KAAM,IAAIR,OAAM,mCAEpB,QAASS,KACL,KAAM,IAAIT,OAAM,qCAsBpB,QAASU,GAAWC,GAChB,GAAIC,IAAqBC,WAErB,MAAOA,YAAWF,EAAK,EAG3B,KAAKC,IAAqBJ,IAAqBI,IAAqBC,WAEhE,MADAD,GAAmBC,WACZA,WAAWF,EAAK,EAE3B,KAEI,MAAOC,GAAiBD,EAAK,GAC/B,MAAMrB,GACJ,IAEI,MAAOsB,GAAiBR,KAAK,KAAMO,EAAK,GAC1C,MAAMrB,GAEJ,MAAOsB,GAAiBR,KAAKU,KAAMH,EAAK,KAMpD,QAASI,GAAgBC,GACrB,GAAIC,IAAuBC,aAEvB,MAAOA,cAAaF,EAGxB,KAAKC,IAAuBR,IAAwBQ,IAAuBC,aAEvE,MADAD,GAAqBC,aACdA,aAAaF,EAExB,KAEI,MAAOC,GAAmBD,GAC5B,MAAO1B,GACL,IAEI,MAAO2B,GAAmBb,KAAK,KAAMY,GACvC,MAAO1B,GAGL,MAAO2B,GAAmBb,KAAKU,KAAME,KAYjD,QAASG,KACAC,GAAaC,IAGlBD,GAAW;AACPC,EAAahB,OACbiB,EAAQD,EAAaE,OAAOD,GAE5BE,GAAa,EAEbF,EAAMjB,QACNoB,KAIR,QAASA,KACL,IAAIL,EAAJ,CAGA,GAAIM,GAAUhB,EAAWS,EACzBC,IAAW,CAGX,KADA,GAAIO,GAAML,EAAMjB,OACVsB,GAAK,CAGP,IAFAN,EAAeC,EACfA,OACSE,EAAaG,GACdN,GACAA,EAAaG,GAAYI,KAGjCJ,IAAa,EACbG,EAAML,EAAMjB,OAEhBgB,EAAe,KACfD,GAAW,EACXL,EAAgBW,IAiBpB,QAASG,GAAKlB,EAAKmB,GACfhB,KAAKH,IAAMA,EACXG,KAAKgB,MAAQA,EAYjB,QAASC,MAhKT,GAOInB,GACAK,EARAe,EAAUzB,EAAOJ,YAgBpB,WACG,IAEQS,EADsB,kBAAfC,YACYA,WAEAL,EAEzB,MAAOlB,GACLsB,EAAmBJ,EAEvB,IAEQS,EADwB,kBAAjBC,cACcA,aAEAT,EAE3B,MAAOnB,GACL2B,EAAqBR,KAuD7B,IAEIY,GAFAC,KACAF,GAAW,EAEXI,GAAa,CAyCjBQ,GAAQC,SAAW,SAAUtB,GACzB,GAAIuB,GAAO,GAAIC,OAAMC,UAAU/B,OAAS,EACxC,IAAI+B,UAAU/B,OAAS,EACnB,IAAK,GAAIP,GAAI,EAAGA,EAAIsC,UAAU/B,OAAQP,IAClCoC,EAAKpC,EAAI,GAAKsC,UAAUtC,EAGhCwB,GAAMe,KAAK,GAAIR,GAAKlB,EAAKuB,IACJ,IAAjBZ,EAAMjB,QAAiBe,GACvBV,EAAWe,IASnBI,EAAKS,UAAUV,IAAM,WACjBd,KAAKH,IAAI4B,MAAM,KAAMzB,KAAKgB,QAE9BE,EAAQQ,MAAQ,UAChBR,EAAQS,SAAU,EAClBT,EAAQU,OACRV,EAAQW,QACRX,EAAQY,QAAU,GAClBZ,EAAQa,YAIRb,EAAQc,GAAKf,EACbC,EAAQe,YAAchB,EACtBC,EAAQgB,KAAOjB,EACfC,EAAQiB,IAAMlB,EACdC,EAAQkB,eAAiBnB,EACzBC,EAAQmB,mBAAqBpB,EAC7BC,EAAQoB,KAAOrB,EAEfC,EAAQqB,QAAU,SAAUC,GACxB,KAAM,IAAItD,OAAM,qCAGpBgC,EAAQuB,IAAM,WAAc,MAAO,KACnCvB,EAAQwB,MAAQ,SAAUC,GACtB,KAAM,IAAIzD,OAAM,mCAEpBgC,EAAQ0B,MAAQ,WAAa,MAAO;AAE9BC,GAAG,SAAStE,EAAQkB,EAAOJ,GAOjC,GAAIyD,GAAWvE,EAAQ,kBACnBwE,EAAWxE,EAAQ,kBAoDnByE,EAAM,SAASC,EAAeC,GAChClD,KAAKiD,cAAgBA,EACrBjD,KAAKkD,WAAaA,EAUpBF,GAAIxB,UAAU2B,QAAU,SAASC,EAAMC,GACrC,GAAIC,GAAQ,MACRtD,KAAKiD,eAAiBjD,KAAKkD,cAC7BI,EAAQ,GAAIP,GACVM,EAAOE,MAAMC,OAAOC,WACpBJ,EAAOE,MAAMC,OAAOE,aACpBL,EAAOE,MAAMC,OAAOG,cAGxB,IAAIC,GAAO5D,IAEX,OAAO,YACL,GAAI6D,GAAW,KACXzC,EAAOC,MAAMG,UAAUsC,MAAMxE,KAAKgC,UACtC,IAAIsC,EAAKX,eAAiBW,EAAKV,WAAY,CACzC,GAAIa,GAAM,IACNH,GAAKV,aACPa,EAAMV,EAAOE,MAAMS,OAAOC,UACxBX,EAAMY,OACNb,EAAOE,MAAMW,SAIfL,EADED,EAAKX,cACI,GAAIH,GAASiB,EAAKT,EAAO,GAAIP,GACtCM,EAAOE,MAAMC,OAAOC,WACpBJ,EAAOE,MAAMC,OAAOE,aACpBL,EAAOE,MAAMW,SAGJ,GAAIpB,GAASiB,EAAK,KAAM,MAGrC3C,EAAKG,KAAKsC,GAGPT,IACHA,EAAOhC,EAAK+C,QAGd,IAAIC,GAAOR,EAAKR,EAChB,IAAoB,kBAATgB,GACT,KAAM,IAAIlF,OAAM,mBAAmBkE,EAAK,IAE1C,IAAIiB,GAASC,OAAOC,OAAOH,EAAK5C,UAEhC,OADA4C,GAAK3C,MAAM4C,EAAQjD,GACZiD,KAMT9F,EAAQ,eACRA,EAAQ,gBACRA,EAAQ,iBACRA,EAAQ,eACRA,EAAQ,uBACRA,EAAQ,eACRA,EAAQ,kBACRA,EAAQ,kBACRA,EAAQ,cACRA,EAAQ,eACRA,EAAQ,eACRA,EAAQ,eACRA,EAAQ,cACRA,EAAQ,cACRA,EAAQ,iBACRA,EAAQ,gBACRA,EAAQ,eACRA,EAAQ,iBACRA,EAAQ,eACRA,EAAQ,gBACRA,EAAQ,mBACRA,EAAQ,gBACRA,EAAQ,eACRA,EAAQ,iBACRA,EAAQ,eACRA,EAAQ,gBACRA,EAAQ,eACRA,EAAQ,mBACRiG,QAAQ,SAAUC;AAClB,GAAIrB,GAAOqB,EAAKjD,UAAUkD,YAAYlC,KAAKmC,aAC3C3B,GAAIxB,UAAU4B,GAAQqB,IAGxBhF,EAAOJ,QAAU2D,IAEd4B,cAAc,EAAEC,eAAe,EAAEC,gBAAgB,EAAEC,cAAc,EAAEC,sBAAsB,EAAEC,cAAc,EAAEC,iBAAiB,GAAGC,iBAAiB,GAAGC,aAAa,GAAGC,cAAc,GAAGC,cAAc,GAAGC,cAAc,GAAGC,aAAa,GAAGC,aAAa,GAAGC,gBAAgB,GAAGC,eAAe,GAAGC,cAAc,GAAGC,gBAAgB,GAAGC,iBAAiB,GAAGC,cAAc,GAAGC,eAAe,GAAGC,kBAAkB,GAAGC,eAAe,GAAGC,iBAAiB,GAAGC,cAAc,GAAGC,gBAAgB,GAAGC,cAAc,GAAGC,eAAe,GAAGC,cAAc,GAAGC,iBAAiB,KAAKC,GAAG,SAASnI,EAAQkB,EAAOJ,GAO7jB,GAAIsH,GAAOpI,EAAQ,gBACfqI,EAAO,QASPvF,EAAQsF,EAAKE,QAAQ,SAAeC,EAAWC,EAAOlD,GACxD8C,EAAKlF,MAAMzB,MAAO4G,EAAM/C,IACxB7D,KAAK+G,MAAQA,EACb/G,KAAK8G,UAAYA,GAGnBrH,GAAOJ,QAAUgC,IAEd2F,eAAe,KAAKC,GAAG,SAAS1I,EAAQkB,EAAOJ,GAOlD,GAAI6H,GAAY3I,EAAQ,eACpBqI,EAAO,SAUPO,EAASD,EAAUL,QAAQ,SAAgBO,EAAMC,EAAOC,EAAUzD,GACpEqD,EAAUzF,MAAMzB,MAAO4G,EAAM/C,IAC7B7D,KAAKsH,SAAWA,EAChBtH,KAAKoH,KAAOA,EACZpH,KAAKqH,MAAQA,GAGf5H,GAAOJ,QAAU8H,IAEdI,cAAc,KAAKC,GAAG,SAASjJ,EAAQkB,EAAOJ,GAOjD,GAAI6H,GAAY3I,EAAQ,eACpBqI,EAAO,QAQPa,EAAQP,EAAUL,QAAQ,SAAezD,EAAMsE,EAAU7D;AAC3DqD,EAAUzF,MAAMzB,MAAOoD,GAAQwD,EAAM/C,IACrC7D,KAAK0H,SAAWA,GAGlBjI,GAAOJ,QAAUoI,IAEdF,cAAc,KAAKI,GAAG,SAASpJ,EAAQkB,EAAOJ,GAOjD,GAAIuI,GAAUrJ,EAAQ,aAClBqI,EAAO,UAOPiB,EAAUD,EAAQf,QAAQ,SAAiBiB,EAAOjE,GACpD+D,EAAQnG,MAAMzB,MAAO4G,EAAMkB,EAAOjE,KAGpCpE,GAAOJ,QAAUwI,IAEdE,YAAY,KAAKC,GAAG,SAASzJ,EAAQkB,EAAOJ,GAO/C,GAAIoI,GAAQlJ,EAAQ,WAChBqI,EAAO,QAcPqB,EAAQR,EAAMZ,QAAQ,SACxBqB,EAASC,EAAY3F,EACrB4F,EAAKC,EAAMX,EAAU7D,GAErB4D,EAAMhG,MAAMzB,MAAO4G,EAAMc,EAAU7D,IACnC7D,KAAKsI,aAAc9F,EACnBxC,KAAKmI,WAAaA,EAClBnI,KAAKkI,QAAUA,EACflI,KAAKwC,KAAOA,EACZxC,KAAK6G,QAAUuB,EACfpI,KAAKuI,WAAaF,GAGpB5I,GAAOJ,QAAU4I,IAEdO,UAAU,IAAIC,GAAG,SAASlK,EAAQkB,EAAOJ,GAO5C,GAAIqJ,GAAWnK,EAAQ,cACnBqI,EAAO,gBAWP+B,EAAgBD,EAAS7B,QAAQ,SAAuBrE,EAAMsF,EAAOc,EAAO/E,GAC9E6E,EAASjH,MAAMzB,MAAOwC,EAAMsF,EAAOjE,IACnC7D,KAAK6I,KAAOjC,EACZ5G,KAAK8I,WAAWF,IAGlBnJ,GAAOJ,QAAUsJ,IAEdI,aAAa,KAAKC,GAAG,SAASzK,EAAQkB,EAAOJ,GAOhD,GAAI6H,GAAY3I,EAAQ,eACpBqI,EAAO,QAQPqC,EAAQ/B,EAAUL,QAAQ,SAAeqC,EAAMrF,GACjDqD,EAAUzF,MAAMzB,MAAO4G,EAAM/C,IAC7B7D,KAAKkJ,KAAOA,GAGdzJ,GAAOJ,QAAU4J,IAEd1B,cAAc,KAAK4B,IAAI,SAAS5K,EAAQkB,EAAOJ,GAOlD,GAAI6H,GAAY3I,EAAQ,eACpBqI,EAAO,WAWPwC,EAAWlC,EAAUL,QAAQ,SAAkBwC,EAAMC,EAAQzF,GAC/DqD,EAAUzF,MAAMzB,MAAO4G,EAAM/C,IAC7B7D,KAAKqJ,KAAOA,EACZrJ,KAAKsJ,OAASA,GAGhB7J,GAAOJ,QAAU+J,IAEd7B,cAAc,KAAKgC,IAAI,SAAShL,EAAQkB,EAAOJ,GAOlD,GAAImK,GAAcjL,EAAQ,iBACtBqI,EAAO,WASP8B,EAAWc,EAAY3C,QAAQ,SAAkBrE,EAAMsF,EAAOjE,GAChE2F,EAAY/H,MAAMzB,MAAO4G,EAAM/C;AAC/B7D,KAAKwC,KAAOA,EACZxC,KAAK8H,MAAQA,GAGfrI,GAAOJ,QAAUqJ,IAEde,gBAAgB,KAAKC,IAAI,SAASnL,EAAQkB,EAAOJ,GAOpD,GAAI6H,GAAY3I,EAAQ,eACpBqI,EAAO,cAOP4C,EAActC,EAAUL,QAAQ,SAAqBzD,EAAMS,GAC7DqD,EAAUzF,MAAMzB,MAAOoD,GAAQwD,EAAM/C,KAQvC2F,GAAYhI,UAAUsH,WAAa,SAASF,KAI5CnJ,EAAOJ,QAAUmK,IAEdjC,cAAc,KAAKoC,IAAI,SAASpL,EAAQkB,EAAOJ,GAOlD,GAAIuK,GAAMrL,EAAQ,SACdqI,EAAO,OAOPiD,EAAOD,EAAI/C,QAAQ,SAAczF,EAAMyC,GACzC+F,EAAInI,MAAMzB,MAAO4G,EAAMxF,EAAMyC,KAG/BpE,GAAOJ,QAAUwK,IAEdC,QAAQ,KAAKC,IAAI,SAASxL,EAAQkB,EAAOJ,GAO5C,GAAIuK,GAAMrL,EAAQ,SACdqI,EAAO,QAOPoD,EAAQJ,EAAI/C,QAAQ,SAAezF,EAAMyC,GAC3C+F,EAAInI,MAAMzB,MAAO4G,EAAMxF,EAAMyC,KAG/BpE,GAAOJ,QAAU2K,IAEdF,QAAQ,KAAKG,IAAI,SAAS1L,EAAQkB,EAAOJ,GAO5C,GAAI6K,GAAO3L,EAAQ,UACfqI,EAAO,QASPuD,EAAQD,EAAKrD,QAAQ,SAAeuD,EAAKtC,EAAOjE,GAClDqG,EAAKzI,MAAMzB,MAAO4G,EAAM/C,IACxB7D,KAAKoK,IAAMA,EACXpK,KAAK8H,MAAQA,GAGfrI,GAAOJ,QAAU8K,IAEdE,SAAS,KAAKC,IAAI,SAAS/L,EAAQkB,EAAOJ,GAO7C,GAAI6K,GAAO3L,EAAQ,UACfqI,EAAO,QAYP1H,EAAQgL,EAAKrD,QAAQ,SAAe0D,EAASC,EAAOC,EAAMC,EAAU7G,GACtEqG,EAAKzI,MAAMzB,MAAO4G,EAAM/C,IACxB7D,KAAKuK,QAAUA,EACfvK,KAAKwK,MAAQA,EACbxK,KAAKyK,KAAOA,EACZzK,KAAK0K,SAAWA,GAGlBjL,GAAOJ,QAAUH,IAEdmL,SAAS,KAAKM,IAAI,SAASpM,EAAQkB,EAAOJ,GAO7C,GAAI6H,GAAY3I,EAAQ,eACpBqI,EAAO,OAQPgE,EAAO1D,EAAUL,QAAQ,SAAcgE,EAAQhH,GACjDqD,EAAUzF,MAAMzB,MAAO4G,EAAM/C,IAC7B7D,KAAK6K,OAASA,GAGhBpL,GAAOJ,QAAUuL,IAEdrD,cAAc,KAAKuD,IAAI,SAASvM,EAAQkB,EAAOJ,GAOlD,GAAI6H,GAAY3I,EAAQ,eACpBqI,EAAO,OAQPmE,EAAO7D,EAAUL,QAAQ,SAAcmE,EAAQnH;AACjDqD,EAAUzF,MAAMzB,MAAO4G,EAAM/C,IAC7B7D,KAAKgL,OAASA,GAGhBvL,GAAOJ,QAAU0L,IAEdxD,cAAc,KAAK0D,IAAI,SAAS1M,EAAQkB,EAAOJ,GAOlD,GAAI6K,GAAO3L,EAAQ,UACfqI,EAAO,aAQPsE,EAAahB,EAAKrD,QAAQ,SAAoBzD,EAAMS,GACtDqG,EAAKzI,MAAMzB,MAAOoD,GAAQwD,EAAM/C,KAGlCpE,GAAOJ,QAAU6L,IAEdb,SAAS,KAAKc,IAAI,SAAS5M,EAAQkB,EAAOJ,GAO7C,GAAI6K,GAAO3L,EAAQ,UACfqI,EAAO,aAUPwE,EAAalB,EAAKrD,QAAQ,SAAoBrE,EAAM6I,EAAKxH,GAC3DqG,EAAKzI,MAAMzB,MAAO4G,EAAM/C,IACxB7D,KAAKwC,KAAOnB,MAAMiK,QAAQ9I,GAAQA,EAAK+I,KAAK,MAAQ/I,EACjC,iBAAR6I,GACTrL,KAAKqL,IAAuB,OAAjBrL,KAAKwC,KAAK,GAErBxC,KAAKqL,IAAMA,GAIf5L,GAAOJ,QAAU+L,IAEdf,SAAS,KAAKmB,IAAI,SAASjN,EAAQkB,EAAOJ,GAO7C,GAAI6H,GAAY3I,EAAQ,eACpBqI,EAAO,UAUP6E,EAAUvE,EAAUL,QAAQ,SAAiB3E,EAAM3D,EAASmN,EAAQ7H,GACtEqD,EAAUzF,MAAMzB,MAAO4G,EAAM/C,IAC7B7D,KAAKkC,KAAOA,EACZlC,KAAKzB,QAAUA,EACfyB,KAAK0L,OAASA,GAGhBjM,GAAOJ,QAAUoM,IAEdlE,cAAc,KAAKoE,IAAI,SAASpN,EAAQkB,EAAOJ,GAOlD,GAAIuI,GAAUrJ,EAAQ,aAClBqI,EAAO,SAOPgF,EAAShE,EAAQf,QAAQ,SAAgBiB,EAAOjE,GAClD+D,EAAQnG,MAAMzB,MAAO4G,EAAMkB,EAAOjE,KAGpCpE,GAAOJ,QAAUuM,IAEd7D,YAAY,KAAK8D,IAAI,SAAStN,EAAQkB,EAAOJ,GAOhD,GAAIuK,GAAMrL,EAAQ,SACdqI,EAAO,QAOPkF,EAAQlC,EAAI/C,QAAQ,SAAezF,EAAMyC,GAC3C+F,EAAInI,MAAMzB,MAAO4G,EAAMxF,EAAMyC,KAG/BpE,GAAOJ,QAAUyM,IAEdhC,QAAQ,KAAKiC,IAAI,SAASxN,EAAQkB,EAAOJ,GAO5C,GAAIsH,GAAOpI,EAAQ,gBACfqI,EAAO,UAQPgB,EAAUjB,EAAKE,QAAQ,SAAiBzD,EAAM0E,EAAOjE,GACvD8C,EAAKlF,MAAMzB,MAAOoD,GAAQwD,EAAM/C,IAChC7D,KAAK8H,MAAQA,GAGfrI,GAAOJ,QAAUuI,IAEdZ,eAAe;GAAKgF,IAAI,SAASzN,EAAQkB,EAAOJ,GAcnD,GAAIyD,GAAW,SAAS+H,EAAQvH,EAAO2I,GACrCjM,KAAK6K,OAASA,EACd7K,KAAKsD,MAAQA,EACbtD,KAAKiM,IAAMA,EAGbxM,GAAOJ,QAAUyD,OAEXoJ,IAAI,SAAS3N,EAAQkB,EAAOJ,GAOlC,GAAIuI,GAAUrJ,EAAQ,aAClBqI,EAAO,QAOPuF,EAAQvE,EAAQf,QAAQ,SAAeiB,EAAOjE,GAChD+D,EAAQnG,MAAMzB,MAAO4G,EAAMkB,EAAOjE,KAGpCpE,GAAOJ,QAAU8M,IAEdpE,YAAY,KAAKqE,IAAI,SAAS7N,EAAQkB,EAAOJ,GAOhD,GAAImK,GAAcjL,EAAQ,iBACtBqI,EAAgB,SAgBhByF,EAAS7C,EAAY3C,QAAQ,SAAgBrE,EAAMpB,EAAMsG,EAAUkB,EAAO/E,GAC5E2F,EAAY/H,MAAMzB,MAAO4G,EAAM/C,IAC/B7D,KAAKwC,KAAOA,EACZxC,KAAKsB,UAAYF,EACjBpB,KAAK0H,SAAWA,EAChB1H,KAAK8I,WAAWF,IAGlBnJ,GAAOJ,QAAUgN,IAEd5C,gBAAgB,KAAK6C,IAAI,SAAS/N,EAAQkB,EAAOJ,GAOpD,GAAIoI,GAAQlJ,EAAQ,WAChB6M,EAAa7M,EAAQ,gBACrBqI,EAAO,YASP2F,EAAY9E,EAAMZ,QAAQ,SAAmBrE,EAAMkF,EAAU8E,EAAc3I,GAC7E4D,EAAMhG,MAAMzB,MAAO4G,EAAMc,EAAU7D,IAC/BrB,YAAgB4I,GAClBpL,KAAKwC,KAAOA,EAEZxC,KAAKwC,KAAO,GAAI4I,GAAW5I,GAE7BxC,KAAKwM,aAAeA,IAAgB,GAGtC/M,GAAOJ,QAAUkN,IAEd/D,UAAU,EAAEiE,eAAe,KAAKC,IAAI,SAASnO,EAAQkB,EAAOJ,GAa/D,GAAI6K,GAAO,SAAcrB,EAAMhF,GAC7B7D,KAAK6I,KAAOA,EACZ7I,KAAK2M,IAAM9I,EAAWA,EAAW,KAQnCqG,GAAKrD,QAAU,SAASnC,GAItB,MAHAA,GAAYlD,UAAY8C,OAAOC,OAAOvE,KAAKwB,WAC3CkD,EAAYmC,QAAU7G,KAAK6G,QAC3BnC,EAAYlD,UAAUkD,YAAcA,EAC7BA,GAGTjF,EAAOJ,QAAU6K,OAEX0C,IAAI,SAASrO,EAAQkB,EAAOJ,GAOlC,GAAIuI,GAAUrJ,EAAQ,aAClBqI,EAAO,SAOPiG,EAAUjF,EAAQf,QAAQ,SAAgBiB,EAAOjE,GACnD+D,EAAQnG,MAAMzB,MAAO4G,EAAMkB,EAAOjE,KAGpCpE,GAAOJ,QAAUwN,IAEd9E,YAAY;GAAK+E,IAAI,SAASvO,EAAQkB,EAAOJ,GAchD,GAAI0D,GAAW,SAAS0H,EAAMsC,EAAQ7I,GACpClE,KAAKyK,KAAOA,EACZzK,KAAK+M,OAASA,EACd/M,KAAKkE,OAASA,EAGhBzE,GAAOJ,QAAU0D,OAEXiK,IAAI,SAASzO,EAAQkB,EAAOJ,GAOlC,GAAIuK,GAAMrL,EAAQ,SACdqI,EAAO,QAOPqG,EAAQrD,EAAI/C,QAAQ,SAAezF,EAAMyC,GAC3C+F,EAAInI,MAAMzB,MAAO4G,EAAMxF,EAAMyC,KAG/BpE,GAAOJ,QAAU4N,IAEdnD,QAAQ,KAAKoD,IAAI,SAAS3O,EAAQkB,EAAOJ,GAO5C,GAAIoI,GAAQlJ,EAAQ,WAChBqI,EAAO,UAQPuG,EAAU1F,EAAMZ,QAAQ,SAAiBa,EAAU0F,EAAQvJ,GAC7D4D,EAAMhG,MAAMzB,MAAO4G,EAAMc,EAAU7D,IACnC7D,KAAKoN,OAASA,GAGhB3N,GAAOJ,QAAU8N,IAEd3E,UAAU,IAAI6E,IAAI,SAAS9O,EAAQkB,EAAOJ,GAO7C,GAAIuI,GAAUrJ,EAAQ,aAClBqI,EAAO,QAQP0G,EAAQ1F,EAAQf,QAAQ,SAAeiB,EAAOjE,GAChD+D,EAAQnG,MAAMzB,MAAO4G,EAAMkB,EAAOjE,KAGpCpE,GAAOJ,QAAUiO,IAEdvF,YAAY,KAAKwF,IAAI,SAAShP,EAAQkB,EAAOJ,GAOhD,GAAI6K,GAAO3L,EAAQ,UACfqI,EAAO,YAOPM,EAAYgD,EAAKrD,QAAQ,SAAmBzD,EAAMS,GACpDqG,EAAKzI,MAAMzB,MAAOoD,GAAQwD,EAAM/C,KAGlCpE,GAAOJ,QAAU6H,IAEdmD,SAAS,KAAKmD,IAAI,SAASjP,EAAQkB,EAAOJ,GAO7C,GAAIuI,GAAUrJ,EAAQ,aAClBqI,EAAO,SASP6G,EAAS7F,EAAQf,QAAQ,SAAgB6G,EAAe5F,EAAOjE,GACjE+D,EAAQnG,MAAMzB,MAAO4G,EAAMkB,EAAOjE,IAClC7D,KAAK0N,cAAgBA,GAGvBjO,GAAOJ,QAAUoO,IAEd1F,YAAY,KAAK4F,IAAI,SAASpP,EAAQkB,EAAOJ,GAOhD,GAAI6H,GAAY3I,EAAQ,eACpBqI,EAAO,MAQPgD,EAAM1C,EAAUL,QAAQ,SAAazD,EAAMhC,EAAMyC,GACnDqD,EAAUzF,MAAMzB,MAAOoD,GAAQwD,EAAM/C,IACrC7D,KAAKsB,UAAYF,GAGnB3B,GAAOJ,QAAUuK,IAEdrC,cAAc,KAAKqG,IAAI,SAASrP,EAAQkB,EAAOJ,GAOlD,GAAIuK,GAAMrL,EAAQ,SACdqI,EAAO,QAOPiH,EAAQjE,EAAI/C,QAAQ,SAAezF,EAAMyC,GAC3C+F,EAAInI,MAAMzB,MAAO4G,EAAMxF,EAAMyC;EAG/BpE,GAAOJ,QAAUwO,IAEd/D,QAAQ,KAAKgE,IAAI,SAASvP,EAAQkB,EAAOJ,GAO5C,GAAIsH,GAAOpI,EAAQ,gBACfqI,EAAO,WAUPmH,EAAWpH,EAAKE,QAAQ,SAAkBmH,EAAYC,EAAOpK,GAC/D8C,EAAKlF,MAAMzB,MAAO4G,EAAM/C,IACxB7D,KAAKgO,WAAaA,EAClBhO,KAAKiO,MAAQA,IAAS,GAGxBxO,GAAOJ,QAAU0O,IAEd/G,eAAe,KAAKkH,IAAI,SAAS3P,EAAQkB,EAAOJ,GAqBnD,GAAIkE,GAAQ,SAAS4K,GACnBnO,KAAKmO,OAASA,EACdnO,KAAKoO,IAAMpO,KAAKmO,OAAOE,OAAOC,MAC9BtO,KAAKuO,IAAM,EACXvO,KAAKwO,YAAa,EAClBxO,KAAKyO,gBAAiB,EACtBzO,KAAK0O,WAAY,EACjB1O,KAAK2O,UAAW,EAChB3O,KAAK4O,YAAa,EAClB5O,KAAK6O,UAAY,EACjB7O,KAAK8O,UACHC,UAAa/O,KAAKoO,IAAIY,UACtBC,UAAajP,KAAKoO,IAAIc,UACtBC,aAAgBnP,KAAKoO,IAAIgB,SACzBC,WAAcrP,KAAKoO,IAAIkB,WACvBC,SAAYvP,KAAKoO,IAAIoB,OACrBC,SAAYzP,KAAKoO,IAAIsB,OACrBC,QAAW3P,KAAKoO,IAAIwB,MACpBC,cAAiB7P,KAAKoO,IAAI0B,OAC1BC,KAAQ/P,KAAKoO,IAAI4B,OACjBC,IAAOjQ,KAAKoO,IAAI4B,OAChBE,SAAYlQ,KAAKoO,IAAI+B,WACrBC,MAASpQ,KAAKoO,IAAIiC,QAClBC,OAAUtQ,KAAKoO,IAAImC,SACnBC,IAAOxQ,KAAKoO,IAAIqC,MAChBC,MAAS1Q,KAAKoO,IAAIuC,QAClBC,QAAW5Q,KAAKoO,IAAIyC,UACpBC,MAAS9Q,KAAKoO,IAAI2C,QAClBC,GAAMhR,KAAKoO,IAAI6C,KACfC,OAAUlR,KAAKoO,IAAI+C,SACnBC,MAASpR,KAAKoO,IAAIiD,QAClBC,KAAQtR,KAAKoO,IAAImD,OACjBC,MAASxR,KAAKoO,IAAIqD,QAClBC,SAAY1R,KAAKoO,IAAIuD,WACrBC,GAAM5R,KAAKoO,IAAIyD,KACfC,IAAO9R,KAAKoO,IAAI2D;AAChBC,OAAUhS,KAAKoO,IAAI6D,SACnBC,QAAWlS,KAAKoO,IAAI+D,UACpBC,WAAcpS,KAAKoO,IAAIiE,aACvBC,QAAWtS,KAAKoO,IAAImE,UACpBC,WAAcxS,KAAKoO,IAAIqE,aACvBC,WAAc1S,KAAKoO,IAAIuE,aACvBC,GAAM5S,KAAKoO,IAAIyE,KACfC,OAAU9S,KAAKoO,IAAI2E,SACnBC,UAAahT,KAAKoO,IAAI6E,YACtBC,KAAQlT,KAAKoO,IAAI+E,OACjBC,QAAWpT,KAAKoO,IAAIiF,UACpBC,MAAStT,KAAKoO,IAAImF,QAClBC,SAAYxT,KAAKoO,IAAIqF,WACrBC,KAAQ1T,KAAKoO,IAAIuF,OACjBC,KAAQ5T,KAAKoO,IAAIyF,OACjBC,MAAS9T,KAAKoO,IAAI2F,QAClBC,MAAShU,KAAKoO,IAAI6F,QAClBC,UAAalU,KAAKoO,IAAI+F,YACtBC,MAASpU,KAAKoO,IAAIiG,QAClBxN,QAAW7G,KAAKoO,IAAIkG,UACpB/L,WAAcvI,KAAKoO,IAAImG,aACvBC,IAAOxU,KAAKoO,IAAIqG,MAChBC,MAAS1U,KAAKoO,IAAIuG,QAClBC,IAAO5U,KAAKoO,IAAIyG,MAChBC,KAAQ9U,KAAKoO,IAAI2G,OACjBC,QAAWhV,KAAKoO,IAAI6G,UACpBC,aAAgBlV,KAAKoO,IAAI+G,eACzB5W,QAAWyB,KAAKoO,IAAIgH,UACpBC,aAAgBrV,KAAKoO,IAAIkH,eACzBC,UAAavV,KAAKoO,IAAIoH,YACtBC,IAAOzV,KAAKoO,IAAIsH,MAChBC,UAAa3V,KAAKoO,IAAIwH,YACtBC,OAAU7V,KAAKoO,IAAI0H,SACnBC,MAAS/V,KAAKoO,IAAI4H,QAClBC,MAASjW,KAAKoO,IAAI8H,QAClBC,gBAAmBnW,KAAKoO,IAAIgI,gBAC5BC,OAAUrW,KAAKoO,IAAIkI,SACnBC,SAAYvW,KAAKoO,IAAIoI,WACrBC,MAASzW,KAAKoO,IAAIsI;AAClBC,QAAW3W,KAAKoO,IAAIwI,UACpBC,UAAa7W,KAAKoO,IAAI0I,YACtBC,OAAU/W,KAAKoO,IAAI4I,SACnBC,MAASjX,KAAKoO,IAAI8I,QAClBC,KAAQnX,KAAKoO,IAAIgJ,OACjBpW,MAAShB,KAAKoO,IAAIiJ,QAClBC,SAAYtX,KAAKoO,IAAImJ,WACrBC,GAAMxX,KAAKoO,IAAIqJ,aACfC,IAAO1X,KAAKoO,IAAIuJ,cAChBC,IAAO5X,KAAKoO,IAAIyJ,eAElB7X,KAAK8X,cACHC,IAAO/X,KAAKoO,IAAI4J,WAChBC,QAAWjY,KAAKoO,IAAI4J,WACpBE,KAAQlY,KAAKoO,IAAI+J,cACjBC,OAAUpY,KAAKoO,IAAI+J,cACnBE,MAASrY,KAAKoO,IAAI+J,cAClBG,OAAUtY,KAAKoO,IAAImK,cACnBC,OAAUxY,KAAKoO,IAAImK,cACnBvX,MAAShB,KAAKoO,IAAIqK,aAClBC,OAAU1Y,KAAKoO,IAAIuK,cACnBC,KAAQ5Y,KAAKoO,IAAIyK,YACjBC,QAAW9Y,KAAKoO,IAAIyK,YACpB5B,MAASjX,KAAKoO,IAAI2K,cAOtBxV,GAAM/B,UAAUwX,SAAW,SAASC,GAsBlC,MArBAjZ,MAAKgE,OAASiV,EACdjZ,KAAKkZ,KAAOD,EAAM1Z,OAClBS,KAAKmZ,SAAW,EAChBnZ,KAAKkE,OAAS,EACdlE,KAAK6O,UAAY,EACjB7O,KAAKoZ,OAAS,GACdpZ,KAAKwD,QACHG,aAAc,EACdF,WAAY,EACZC,aAAc,EACd2V,UAAW,EACXC,YAAa,GAEftZ,KAAKqO,UACLrO,KAAKuZ,kBACLvZ,KAAKwZ,KAAOxZ,KAAKkE,QAAUlE,KAAKkZ,MAC3BlZ,KAAKwO,YAAcxO,KAAK0O,UAC3B1O,KAAKyZ,MAAM,mBAEXzZ,KAAKyZ,MAAM,WAENzZ,MAOTuD,EAAM/B,UAAUyX,MAAQ,SAASC;AAC/B,GAAIQ,GAAK1Z,KAAKgE,OAAOhE,KAAKkE,OAC1B,OAAKwV,IACL1Z,KAAKoZ,QAAUM,EACf1Z,KAAKkE,SACO,OAAPwV,GAA4C,OAA7B1Z,KAAKgE,OAAOhE,KAAKkE,UACnClE,KAAKoZ,QAAU,KACfpZ,KAAKkE,UAEI,OAAPwV,GAAsB,OAAPA,GACjB1Z,KAAKwD,OAAO6V,YAAcrZ,KAAKmZ,SAC/BnZ,KAAK6O,UAAY7O,KAAKwD,OAAO8V,YAC7BtZ,KAAKwD,OAAO8V,YAAc,GAE1BtZ,KAAKwD,OAAO8V,cAEPI,GAdS,IAoBlBnW,EAAM/B,UAAUmY,MAAQ,SAAST,GAC/B,GAAa,IAATA,EAEFlZ,KAAKkE,SAC4B,OAA7BlE,KAAKgE,OAAOhE,KAAKkE,SAAqD,OAAjClE,KAAKgE,OAAOhE,KAAKkE,OAAS,KACjElE,KAAKkE,SACLgV,KAE+B,OAA7BlZ,KAAKgE,OAAOhE,KAAKkE,SAAiD,OAA7BlE,KAAKgE,OAAOhE,KAAKkE,UACxDlE,KAAKwD,OAAO6V,YACZrZ,KAAKmZ,WACLnZ,KAAKwD,OAAO8V,YAActZ,KAAK6O,WAEjC7O,KAAKoZ,OAASpZ,KAAKoZ,OAAOnV,UAAU,EAAGjE,KAAKoZ,OAAO7Z,OAAS2Z,OACvD,IAAIA,EAAO,EAEhB,GADAlZ,KAAKkE,QAAUgV,EACXA,EAAOlZ,KAAKoZ,OAAO7Z,OAAQ,CAC7BS,KAAKoZ,OAASpZ,KAAKoZ,OAAOnV,UAAU,EAAGjE,KAAKoZ,OAAO7Z,OAAS2Z,GAE5DlZ,KAAKwD,OAAO6V,UAAYrZ,KAAKwD,OAAOC,WACpCzD,KAAKwD,OAAOoW,SAAW5Z,KAAK6O,UAAY7O,KAAKwD,OAAOqW,SACpD,KAAI,GAAI7a,GAAI,EAAGA,EAAIgB,KAAKoZ,OAAO7Z,OAAQP,IAAK,CAC1C,GAAI8a,GAAI9Z,KAAKoZ,OAAOpa,EACV,QAAN8a,GACFA,EAAI9Z,KAAKoZ,SAASpa,GAClBgB,KAAK6O,UAAY7O,KAAKwD,OAAOoW,SAC7B5Z,KAAKwD,OAAO6V,YACZrZ,KAAKwD,OAAOoW,SAAW;AACb,OAANE,IACQ,OAANA,EACF9Z,KAAKwD,OAAO6V,YAEZrZ,KAAKwD,OAAOoW,aAGD,OAANE,GACT9Z,KAAK6O,UAAY7O,KAAKwD,OAAOoW,SAC7B5Z,KAAKwD,OAAO6V,YACZrZ,KAAKwD,OAAOoW,SAAW,GAEvB5Z,KAAKwD,OAAOoW,WAGhB5Z,KAAKmZ,SAAWnZ,KAAKwD,OAAO6V,cAG5BrZ,MAAKoZ,OAAS,GACdpZ,KAAKwD,OAAO6V,UAAYrZ,KAAKmZ,SAAWnZ,KAAKwD,OAAOC,WACpDzD,KAAKwD,OAAO8V,YAActZ,KAAKwD,OAAOE,YAI1C,OAAO1D,OAITuD,EAAM/B,UAAUuY,SAAW,SAASC,GAClC,MAAOA,KAASha,KAAKia,MAAMD,EAAKza,SAIlCgE,EAAM/B,UAAU0Y,iBAAmB,SAASF,GAC1C,MAAOA,KAASha,KAAKia,MAAMD,EAAKza,QAAQoF,eAI1CpB,EAAM/B,UAAUyY,MAAQ,SAASf,GAC/B,GAAIc,GAAOha,KAAKgE,OAAOC,UAAUjE,KAAKkE,OAAQlE,KAAKkE,OAASgV,EAI5D,OAH8B,OAA1Bc,EAAKA,EAAKza,OAAS,IAAuD,OAAxCS,KAAKgE,OAAOhE,KAAKkE,OAASgV,EAAO,KACrEc,GAAQ,MAEHA,GAITzW,EAAM/B,UAAU2Y,QAAU,SAASjB,GACjC,IAAI,GAAIla,GAAI,EAAGA,EAAIka,EAAMla,IAAK,CAC5B,GAAI0a,GAAK1Z,KAAKgE,OAAOhE,KAAKkE,OAC1B,KAAKwV,EAAI,KACT1Z,MAAKoZ,QAAUM,EACf1Z,KAAKkE,SACO,OAAPwV,GAA4C,OAA7B1Z,KAAKgE,OAAOhE,KAAKkE,UACnClE,KAAKoZ,QAAU,KACfpZ,KAAKkE,SACLlF,KAES,OAAP0a,GAAsB,OAAPA,GACjB1Z,KAAKwD,OAAO6V,YAAcrZ,KAAKmZ,SAC/BnZ,KAAK6O,UAAY7O,KAAKwD,OAAO8V,YAC7BtZ,KAAKwD,OAAO8V,YAAc,GAE1BtZ,KAAKwD,OAAO8V;CAGhB,MAAOtZ,OAMTuD,EAAM/B,UAAU4Y,SAAW,WACzB,OACEhB,OAAQpZ,KAAKoZ,OACblV,OAAQlE,KAAKkE,OACbiV,SAAUnZ,KAAKmZ,SACftK,UAAW7O,KAAK6O,UAChBrL,QACEG,aAAc3D,KAAKwD,OAAOG,aAC1BF,WAAYzD,KAAKwD,OAAOC,WACxBC,aAAc1D,KAAKwD,OAAOE,aAC1B2V,UAAWrZ,KAAKwD,OAAO6V,UACvBC,YAAatZ,KAAKwD,OAAO8V,eAQ/B/V,EAAM/B,UAAU6Y,SAAW,SAASC,GAMlC,MALAta,MAAKoZ,OAASkB,EAAMlB,OACpBpZ,KAAKkE,OAASoW,EAAMpW,OACpBlE,KAAKmZ,SAAWmB,EAAMnB,SACtBnZ,KAAK6O,UAAYyL,EAAMzL,UACvB7O,KAAKwD,OAAS8W,EAAM9W,OACbxD,MAITuD,EAAM/B,UAAU+Y,YAAc,SAASzS,EAAOmS,GAE5C,MADAja,MAAKqO,OAAO9M,MAAMuG,EAAOmS,IAClBja,MAITuD,EAAM/B,UAAUgZ,IAAM,WACpB,GAAIhQ,GAAQxK,KAAKya,QAAUza,KAAKwa,KAChC,KAAKxa,KAAKwO,WAAY,CACpB,KACEhE,IAAUxK,KAAKoO,IAAIsM,eAEhB1a,KAAKyO,iBACJjE,IAAUxK,KAAKoO,IAAIuM,WAChBnQ,IAAUxK,KAAKoO,IAAIwM,iBAIvB5a,KAAK0O,WACHlE,IAAUxK,KAAKoO,IAAIyM,YAKxBrQ,EAAQxK,KAAKya,QAAUza,KAAKwa,KAE9B,KAAKxa,KAAK0O,WAAalE,GAASxK,KAAKoO,IAAI0M,qBAEvC,MAAO9a,MAAKoO,IAAIyF,OAGpB,MAAOrJ,IAITjH,EAAM/B,UAAUiY,MAAQ,SAASsB,GAI/B,GAHA/a,KAAKuZ,eAAehY,KAAKwZ,GACzB/a,KAAKgb,aAAeD,EACpB/a,KAAKib,QAAUjb,KAAK,QAAU+a,GACF,kBAAjB/a,MAAKib,QACd,KAAM,IAAI/b,OAAM,8BAA8B6b,EAAU;AAE1D,MAAO/a,OAITuD,EAAM/B,UAAU0Z,SAAW,WACzB,GAAIxc,GAAIsB,KAAKuZ,eAAeha,OAAS,EACjCwb,EAAarc,EAAI,EAAKsB,KAAKuZ,eAAe4B,MAAQnb,KAAKuZ,eAAe,EAG1E,IAFAvZ,KAAKgb,aAAehb,KAAKuZ,eAAevZ,KAAKuZ,eAAeha,OAAS,GACrES,KAAKib,QAAUjb,KAAK,QAAUA,KAAKgb,cACP,kBAAjBhb,MAAKib,QACd,KAAM,IAAI/b,OAAM,8BAA8Bc,KAAKgb,aAAa,IAElE,OAAOD,IAITxX,EAAM/B,UAAUiZ,KAAO,WACrB,GAAIjQ,EAIJ,OAHKxK,MAAKgE,SACRhE,KAAKwZ,MAAO,GAEVxZ,KAAKwZ,KACAxZ,KAAKuO,KAEdvO,KAAKwD,OAAOG,aAAe3D,KAAKkE,OAChClE,KAAKwD,OAAOC,WAAazD,KAAKwD,OAAO6V,UACrCrZ,KAAKwD,OAAOE,aAAe1D,KAAKwD,OAAO8V,YACvCtZ,KAAKoZ,OAAS,GACVpZ,KAAKqO,OAAO9O,OAAS,GACvBiL,EAAQxK,KAAKqO,OAAOlK,QACI,gBAAbqG,GAAM,GACfxK,KAAKqa,SAAS7P,EAAM,IAEpBxK,KAAKma,QAAQ3P,EAAM,IAErBA,EAAQA,EAAM,IAEdA,EAAQxK,KAAKib,QAAQxZ,MAAMzB,SAEzBA,KAAKkE,QAAUlE,KAAKkZ,MAA+B,IAAvBlZ,KAAKqO,OAAO9O,SAC1CS,KAAKwZ,MAAO,GAEPhP,KAMPjM,EAAQ,uBACRA,EAAQ,sBACRA,EAAQ,sBACRA,EAAQ,uBACRA,EAAQ,wBACRA,EAAQ,sBACRA,EAAQ,qBACRA,EAAQ,qBACRiG,QAAQ,SAAU4D,GAClB,IAAI,GAAIgT,KAAKhT,GACX7E,EAAM/B,UAAU4Z,GAAKhT,EAAIgT;GAI7B3b,EAAOJ,QAAUkE,IAEd8X,sBAAsB,GAAGC,qBAAqB,GAAGC,qBAAqB,GAAGC,sBAAsB,GAAGC,uBAAuB,GAAGC,qBAAqB,GAAGC,oBAAoB,GAAGC,mBAAmB,KAAKC,IAAI,SAAStd,EAAQkB,EAAOJ,GAMlOI,EAAOJ,SACLsb,UAAW,WACT,KAAM3a,KAAKkE,OAASlE,KAAKkZ,MAAM,CAC7B,GAAIQ,GAAK1Z,KAAKiZ,OACd,IAAW,OAAPS,GAAsB,OAAPA,EACjB,MAAO1Z,MAAKoO,IAAIuM,SACX,IAAW,MAAPjB,IAAe1Z,KAAK8b,YAA2C,MAA7B9b,KAAKgE,OAAOhE,KAAKkE,QAE5D,MADAlE,MAAK2Z,MAAM,GACJ3Z,KAAKoO,IAAIuM,SACX,IAAW,MAAPjB,GAAc1Z,KAAK8b,YAA2C,MAA7B9b,KAAKgE,OAAOhE,KAAKkE,QAE3D,MADAlE,MAAK2Z,MAAM,GACJoC,MAAM3N,IAAIuM,UAGrB,MAAO3a,MAAKoO,IAAIuM,WAKlBC,cAAe,WACb,GAAIlB,GAAK1Z,KAAKiZ,QACVzO,EAAQxK,KAAKoO,IAAIuM,SACrB,IAAW,MAAPjB,EAAY,CAKd,GAJAA,EAAK1Z,KAAKiZ,QACNjZ,KAAKgc,kBACPxR,EAAQxK,KAAKoO,IAAIwM,eAER,MAAPlB,EACF,MAAOlP,EAEPxK,MAAK2Z,MAAM,GAGf,KAAM3Z,KAAKkE,OAASlE,KAAKkZ,MAEvB,GADAQ,EAAK1Z,KAAKiZ,QACC,MAAPS,GAA2C,MAA7B1Z,KAAKgE,OAAOhE,KAAKkE,QAAiB,CAClDlE,KAAKiZ,OACL,OAGJ,MAAOzO,UAILyR,IAAI,SAAS1d,EAAQkB,EAAOJ,GAMlCI,EAAOJ,SACL6c,YAAa,WAUX,MARElc,MAAKuZ,eAAeha,OAAS,GAC+B,YAAzDS,KAAKuZ,eAAevZ,KAAKuZ,eAAeha,OAAS,GAGpDS,KAAKkb,WAELlb,KAAKyZ,MAAM;AAENzZ,MAETmc,aAAc,WACZ,KAAMnc,KAAKkE,OAASlE,KAAKkZ,MAAM,CAC7B,GAAIQ,GAAK1Z,KAAKiZ,OACd,IAAU,KAANS,EAEF,GADAA,EAAK1Z,KAAKia,MAAM,GACN,KAANP,EAAW,CACb,GAAI1Z,KAAK+Z,SAAS,MAAO,CACvB/Z,KAAK2Z,MAAM,GAAGY,YAAYva,KAAKoO,IAAI0M,qBAAsB,GAAGoB,aAC5D,OACK,GAAIlc,KAAKka,iBAAiB,UAC/BR,EAAK1Z,KAAKgE,OAAOhE,KAAKkE,OAAS,GACpB,MAAPwV,GAAqB,OAAPA,GAAsB,OAAPA,GAAsB,OAAPA,GAAa,CAC3D1Z,KAAK2Z,MAAM,GAAGY,YAAYva,KAAKoO,IAAIyM,WAAY,GAAGqB,aAClD,OAGJ,GAAIlc,KAAK4O,WAAY,CACnB5O,KAAK2Z,MAAM,GAAGY,YAAYva,KAAKoO,IAAIyM,WAAY,GAAGqB,aAClD,YAEG,IAAGlc,KAAK2O,UAAkB,KAAN+K,EAAW,CACpC,GAAI1Z,KAAK+Z,SAAS,MAAO,CACvB/Z,KAAK8b,YAAa,EAClB9b,KAAK2Z,MAAM,GAAGY,YAAYva,KAAKoO,IAAI0M,qBAAsB,GAAGoB,aAC5D,OAEAlc,KAAK8b,YAAa,EAClB9b,KAAK2Z,MAAM,GAAGY,YAAYva,KAAKoO,IAAIyM,WAAY,GAAGqB,aAClD,QAKR,MAAIlc,MAAKoZ,OAAO7Z,OAAS,GAChBS,KAAKoO,IAAIgO,qBAOhBC,IAAI,SAAS9d,EAAQkB,EAAOJ,IAClC,SAAW6B,GAQX,GAAoB,OAAhBA,EAAQob,KACV,GACIC,GAAqB,GACrBC,EAAkB,0BAEtB,IACID,GAAqB,GACrBC,EAAkB,YAGxB/c,GAAOJ,SACLod,YAAa,WACX,GAAI/C,GAAK1Z,KAAKoZ,OAAO,GACjBsD,EAA8B,MAAnB1c,KAAKoZ,OAAO,EAC3B,IAAW,MAAPM,EAGF,GAFAA,EAAK1Z,KAAKiZ,QAEC,MAAPS,GAAqB,MAAPA,EAAY,CAE5B,GADA1Z,KAAKiZ;AACDjZ,KAAK2c,SACP,MAAO3c,MAAK4c,cAEZ5c,MAAK2Z,MAAM,OAER,IAAW,MAAPD,GAAqB,MAAPA,EAAY,CAEnC,GADAA,EAAK1Z,KAAKiZ,QACC,MAAPS,GAAqB,MAAPA,EAChB,MAAO1Z,MAAK6c,cAEZ7c,MAAK2Z,MAAM,OAEH3Z,MAAK8c,UACf9c,KAAK2Z,MAAM,EAIf,MAAM3Z,KAAKkE,OAASlE,KAAKkZ,MAEvB,GADAQ,EAAK1Z,KAAKiZ,SACLjZ,KAAK8c,SAAU,CAClB,GAAW,MAAPpD,GAAegD,EAEZ,CAAA,GAAW,MAAPhD,GAAqB,MAAPA,EAAY,CAEnC,GADAA,EAAK1Z,KAAKiZ,QACC,MAAPS,GAAqB,MAAPA,EAAY,CAE5B,GADAA,EAAK1Z,KAAKiZ,QACNjZ,KAAK8c,SAEP,MADA9c,MAAK+c,eACE/c,KAAKoO,IAAI4O,SAEhBhd,MAAK2Z,MAAM,EACX,OAEG,GAAI3Z,KAAK8c,SAEd,MADA9c,MAAK+c,eACE/c,KAAKoO,IAAI4O,SAEhBhd,MAAK2Z,MAAM,EACX,OAGF3Z,KAAK2Z,MAAM,EACX,OArBA+C,GAAW,EAyBjB,MAAIA,GACK1c,KAAKoO,IAAI4O,UACPhd,KAAKoZ,OAAO7Z,OAASgd,EAAqB,EAC5Cvc,KAAKoO,IAAI6O,UAGdjd,KAAKoZ,OAAO7Z,QAAUgd,GACnBvc,KAAKoZ,OAASoD,EAEVxc,KAAKoO,IAAI6O,UAEXjd,KAAKoO,IAAI4O,WAIpBJ,aAAc,WACZ,KAAM5c,KAAKkE,OAASlE,KAAKkZ,MAEvB,GADAlZ,KAAKiZ,SACAjZ,KAAK2c,SAAU,CAClB3c,KAAK2Z,MAAM,EACX,OAGJ,MAAO3Z,MAAKoO,IAAI6O,WAGlBF,aAAc,WACZ,KAAM/c,KAAKkE,OAASlE,KAAKkZ,MAEvB,GADAlZ,KAAKiZ,SACAjZ,KAAK8c,SAAU,CAClB9c,KAAK2Z,MAAM,EACX,OAGJ,MAAO3Z,MAAKoO,IAAI6O,WAGlBJ,aAAc,WAEZ,IADA,GAAInD,GACE1Z,KAAKkE,OAASlE,KAAKkZ,MAEvB,GADAQ,EAAK1Z,KAAKiZ,QACC,MAAPS,GAAqB,MAAPA,EAAY;AAC5B1Z,KAAK2Z,MAAM,EACX,OAGJ,MAAO3Z,MAAKoO,IAAI6O,cAIjB3d,KAAKU,KAAKzB,EAAQ,eAClB2e,SAAW,IAAIC,IAAI,SAAS5e,EAAQkB,EAAOJ,GAM9CI,EAAOJ,SACL+d,6BAA8B,WAC5B,GAAI1D,GAAK1Z,KAAKiZ,OACd,IAAW,MAAPS,EAAY,CAEd,GADAA,EAAK1Z,KAAKiZ,QACC,MAAPS,EACF,MAAO1Z,MAAKoO,IAAIiP,iBAElBrd,MAAK2Z,MAAM,OACN,IAAI3Z,KAAKsd,iBAEd,MADAtd,MAAKud,gBACEvd,KAAKoO,IAAIoP,QAIlB,OAFAxd,MAAKkb,WACLlb,KAAK2Z,MAAM,IACJ,GAET8D,4BAA6B,WAC3B,GAAI/D,GAAK1Z,KAAKiZ,OACd,OAAIjZ,MAAKsd,kBACPtd,KAAKud,gBACL7D,EAAK1Z,KAAKiZ,QACVjZ,KAAKkb,WACM,MAAPxB,GAAqB,MAAPA,GAChB1Z,KAAKyZ,MAAM,mBACXzZ,KAAK2Z,MAAM,GACJ3Z,KAAKoO,IAAIsP,mBAEhB1d,KAAK2Z,MAAM3Z,KAAKoZ,OAAO7Z,SAChB,KAGTS,KAAK2Z,MAAM,GACX3Z,KAAKkb,WACLlb,KAAKyZ,MAAM,oBAEJ,IAGXkE,mBAAoB,WAClB,GAAIjE,GAAK1Z,KAAKiZ,OACd,IAAIjZ,KAAK8c,SAEP,MADA9c,MAAKyc,cACEzc,KAAKoO,IAAIwP,YACX,IAAW,MAAPlE,EAET,MADA1Z,MAAKkb,WACE,GACF,IAAW,MAAPxB,EAAY,CAErB,GADA1Z,KAAKiZ,QACDjZ,KAAKsd,iBAEP,MADAtd,MAAKud,gBACEvd,KAAKoO,IAAIyP,UAEhB,MAAM,IAAI3e,OAAM,uBAEb,GAAIc,KAAKsd,iBAEd,MADAtd,MAAKud;AACEvd,KAAKoO,IAAIoP,QACX,IAAIxd,KAAKgc,iBAA0B,OAAPtC,GAAsB,MAAPA,GAAsB,MAAPA,EAC/D,MAAO1Z,MAAKoO,IAAI0P,yBACX,IAAW,MAAPpE,GAAqB,MAAPA,GAAqB,MAAPA,GAAqB,MAAPA,GAAqB,MAAPA,GAAc1Z,KAAK+d,WACpF,MAAOrE,EAEP,MAAM,IAAIxa,OAAM,8BAKhB8e,IAAI,SAASzf,EAAQkB,EAAOJ,GAMlCI,EAAOJ,SACL4e,qBAAsB,WACpB,GAAIvE,GAAK1Z,KAAKiZ,OACd,QAAOS,GACL,IAAK,IACL,IAAK,KACL,IAAK,KACL,IAAK,KACL,IAAK,OACH,MAAO1Z,MAAK0a,cACd,KAAK,IACH,MAAO1a,MAAK2a,WACd,KAAK,IACH,MAAiC,MAA7B3a,KAAKgE,OAAOhE,KAAKkE,QACZlE,KAAK2a,YAC0B,MAA7B3a,KAAKgE,OAAOhE,KAAKkE,SAC1BlE,KAAKiZ,QACEjZ,KAAK4a,iBAEP5a,KAAKke,eACd,KAAK,IACH,MAAOle,MAAKme,4BACd,KAAK,IACH,MAAOne,MAAKoe,kBACd,KAAK,IAEH,MADApe,MAAKyZ,MAAM,gBACJ,GACT,KAAK,IACH,IAAKzZ,KAAK8b,YAAc9b,KAAK+Z,SAAS,KAAM,CAC1C/Z,KAAKiZ,OACL,IAAIoF,GAASre,KAAKgE,OAAOhE,KAAKkE,OAK9B,OAJe,OAAXma,GAA8B,OAAXA,GAAiBre,KAAKiZ,QACzCjZ,KAAKuZ,eAAeha,OAAS,GAC/BS,KAAKyZ,MAAM,WAENzZ,KAAKoO,IAAIkQ,YAElB,MAAOte,MAAKke,eACd,KAAK,IACH,MAAIle,MAAK8b,YAA2C,MAA7B9b,KAAKgE,OAAOhE,KAAKkE,SACtClE,KAAKiZ,QACLS,EAAK1Z,KAAKgE,OAAOhE,KAAKkE;AACX,OAAPwV,GAAsB,OAAPA,GACjB1Z,KAAKiZ,QAEPjZ,KAAK8b,YAAa,EACd9b,KAAKuZ,eAAeha,OAAS,GAC/BS,KAAKyZ,MAAM,WAENzZ,KAAKoO,IAAIkQ,aAEXte,KAAKke,eACd,KAAK,IAEH,MADAle,MAAKyZ,MAAM,mBACJ,GACT,KAAK,IAKH,MAJIzZ,MAAKuZ,eAAeha,OAAS,GAE/BS,KAAKkb,WAEA,GACT,SACE,GAAW,MAAPxB,EAAY,CAEd,GADA1Z,KAAKiZ,QACDjZ,KAAK8c,SACP,MAAO9c,MAAKyc,aAEZzc,MAAK2Z,MAAM,GAGf,GAAI3Z,KAAK8c,SACP,MAAO9c,MAAKyc,aACP,IAAIzc,KAAKsd,iBACd,MAAOtd,MAAKud,gBAAgBC,UACvB,IAAGxd,KAAK+d,WACb,MAAO/d,MAAKke,gBAGlB,KAAM,IAAIhf,OACR,0BAA4Bwa,EAAK,aAAe1Z,KAAKmZ,SAAW,YAAcnZ,KAAKkE,OAAS,MAIhGwW,aAAc,WACZ,KAAM1a,KAAKkE,OAASlE,KAAKkZ,MAAM,CAC7B,GAAIQ,GAAK1Z,KAAKiZ,OACd,IAAW,MAAPS,GAAqB,OAAPA,GAAsB,OAAPA,GAAsB,OAAPA,EAAhD,CAGA1Z,KAAK2Z,MAAM,EACX,QAEF,MAAO3Z,MAAKoO,IAAIsM,oBAId6D,IAAI,SAAShgB,EAAQkB,EAAOJ,GAMlCI,EAAOJ,SACL8e,2BAA4B,WAE1B,IADA,GAAIzE,GACE1Z,KAAKkE,OAASlE,KAAKkZ,MAEvB,GADAQ,EAAK1Z,KAAKiZ,QACA,MAANS,EACF1Z,KAAKiZ,YACA,IAAU,KAANS,EACT,KAGJ,OAAO1Z,MAAKoO,IAAI+P,4BAGlBK,WAAY,WACV,GAAIC,GAASze,KAAKkE,MAClB,IACmC,MAAjClE,KAAKgE,OAAOhE,KAAKkE,OAAS,IACM,MAA7BlE,KAAKgE,OAAOhE,KAAKkE,SACgB,MAAjClE,KAAKgE,OAAOhE,KAAKkE,OAAS,GAC7B;AAIA,GAHAlE,KAAKkE,QAAU,EAGXlE,KAAK0e,cACP,KAAM1e,KAAKkE,OAASlE,KAAKkZ,OACvBlZ,KAAKkE,SACAlE,KAAK0e,iBAOd,GAAIC,GAAQ3e,KAAKgE,OAAOhE,KAAKkE,OAAS,EAQtC,IAPc,MAAVya,GAA4B,MAAVA,EACpB3e,KAAKkE,SAELya,EAAQ,KAIN3e,KAAKsd,iBAAkB,CAEzB,IADA,GAAIsB,GAAW5e,KAAKkE,OAAS,EACvBlE,KAAKkE,OAASlE,KAAKkZ,OACvBlZ,KAAKkE,SACAlE,KAAK6e,cAIZ,GAAIC,GAAU9e,KAAKgE,OAAOC,UAAU2a,EAAU5e,KAAKkE,OAAS,EAC5D,MAAKya,GAASA,IAAU3e,KAAKgE,OAAOhE,KAAKkE,OAAS,MAC5Cya,GAAO3e,KAAKkE,SAEqB,OAAjClE,KAAKgE,OAAOhE,KAAKkE,OAAS,IAAgD,OAAjClE,KAAKgE,OAAOhE,KAAKkE,OAAS,IAWrE,MATAlE,MAAK+e,cAAgBD,EACrBF,EAAW5e,KAAKkE,OAASua,EACzBze,KAAKkE,OAASua,EACdze,KAAKma,QAAQyE,GACC,MAAVD,EACF3e,KAAKyZ,MAAM,aAEXzZ,KAAKyZ,MAAM,cAENzZ,KAAKoO,IAAI4Q,iBAMxB,MADAhf,MAAKkE,OAASua,GACP,GAETL,iBAAkB,WAEhB,IADA,GAAI1E,GACE1Z,KAAKkE,OAASlE,KAAKkZ,MAEvB,GADAQ,EAAK1Z,KAAKiZ,QACA,MAANS,EACF1Z,KAAKiZ,YACA,CAAA,GAAU,KAANS,EACT,KACK,IAAU,KAANA,EAAW,CAEpB,GADAA,EAAK1Z,KAAKiZ,QACC,KAANS,GAAa1Z,KAAKsd,iBAAkB,CACvCtd,KAAK2Z,MAAM,EACX,OAEF3Z,KAAK2Z,MAAM,OACN,IAAU,KAAND,EAAW,CAEpB,GADAA,EAAK1Z,KAAKiZ,QACA,KAANS,EAAW,CACb1Z,KAAK2Z,MAAM,EACX,OAEF3Z,KAAK2Z,MAAM,IAGf,GAAU,KAAND,EACF,MAAO1Z,MAAKoO,IAAI+P,0BAEhB,IAAIc,GAAS,CAYb,OAXuB,MAAnBjf,KAAKoZ,OAAO,IAAiC,MAAnBpZ,KAAKoZ,OAAO,KACxC6F,EAAS;AAEPjf,KAAKoZ,OAAO7Z,OAAS,GACvBS,KAAKua,YACHva,KAAKoO,IAAI0P,0BACT9d,KAAKoZ,OAAO7Z,OAAS0f,GAGzBjf,KAAK2Z,MAAM3Z,KAAKoZ,OAAO7Z,OAAS0f,GAChCjf,KAAKyZ,MAAM,oBACJzZ,KAAKoZ,QAKhB8F,YAAa,WAEX,GAAIlf,KAAKgE,OAAOC,UAAUjE,KAAKkE,OAAS,EAAGlE,KAAKkE,OAAS,EAAIlE,KAAK+e,cAAcxf,UAAYS,KAAK+e,cAAe,CAC9G,GAAIrF,GAAK1Z,KAAKgE,OAAOhE,KAAKkE,OAAS,EAAIlE,KAAK+e,cAAcxf,OAC1D,IAAW,OAAPma,GAAsB,OAAPA,GAAsB,MAAPA,EAChC,OAAO,EAGX,OAAO,GAGTyF,eAAgB,WAEd,GAAInf,KAAKkf,cAGP,MAFAlf,MAAKma,QAAQna,KAAK+e,cAAcxf,QAChCS,KAAKkb,WACElb,KAAKoO,IAAIgR,aAIlB,KADA,GAAI1F,GAAK1Z,KAAKgE,OAAOhE,KAAKkE,OAAS,GAC7BlE,KAAKkE,OAASlE,KAAKkZ,MACvB,GAAW,OAAPQ,GAAsB,OAAPA,GAEjB,GADAA,EAAK1Z,KAAKiZ,QACNjZ,KAAKkf,cAKP,MAJAlf,MAAK2Z,MAAM,GAAGuB,WACdlb,KAAKua,YACHva,KAAKoO,IAAIgR,cAAepf,KAAK+e,cAAcxf,QAEtCS,KAAKoO,IAAI0P,8BAGlBpE,GAAK1Z,KAAKiZ,OAId,OAAOjZ,MAAKoO,IAAI0P,2BAGlBuB,gBAAiB,WAEf,GAAI3F,GAAK1Z,KAAKiZ,OACd,IAAIjZ,KAAKkf,cAGP,MAFAlf,MAAKma,QAAQna,KAAK+e,cAAcxf,OAAS,GACzCS,KAAKkb,WACElb,KAAKoO,IAAIgR,aAGlB,MAAMpf,KAAKkE,OAASlE,KAAKkZ,MASvB,GAPW,OAAPQ,IACFA,EAAK1Z,KAAKiZ;AACC,OAAPS,GAAsB,OAAPA,IACjBA,EAAK1Z,KAAKiZ,UAIH,OAAPS,GAAsB,OAAPA,GAEjB,GADAA,EAAK1Z,KAAKiZ,QACNjZ,KAAKkf,cAKP,MAJAlf,MAAK2Z,MAAM,GAAGuB,WACdlb,KAAKua,YACHva,KAAKoO,IAAIgR,cAAepf,KAAK+e,cAAcxf,QAEtCS,KAAKoO,IAAI0P,8BAEb,IAAW,MAAPpE,EAAY,CAErB,GADAA,EAAK1Z,KAAKiZ,QACC,MAAPS,EAGF,MADA1Z,MAAKyZ,MAAM,0BACPzZ,KAAKoZ,OAAO7Z,OAAS,GACvBS,KAAKua,YAAYva,KAAKoO,IAAIkR,2BAA4B,GACtDtf,KAAK2Z,MAAM,GACJ3Z,KAAKoO,IAAI0P,2BAET9d,KAAKoO,IAAIkR,0BAEb,IAAItf,KAAKsd,iBAAkB,CAEhC,GAAIsB,GAAW5e,KAAKkE,OAChBuW,EAAOza,KAAKuf,kBAChB,OAAIvf,MAAKoZ,OAAO7Z,OAASS,KAAKkE,OAAS0a,EAAW,GAChD5e,KAAKua,YAAYE,EAAMza,KAAKkE,OAAS0a,EAAW,GAChD5e,KAAK2Z,MAAM3Z,KAAKkE,OAAS0a,EAAW,GAC7B5e,KAAKoO,IAAI0P,2BAETrD,OAIN,IAAW,MAAPf,GAET,GADAA,EAAK1Z,KAAKiZ,QACC,MAAPS,EAGF,MADA1Z,MAAKyZ,MAAM,mBACPzZ,KAAKoZ,OAAO7Z,OAAS,GACvBS,KAAKua,YAAYva,KAAKoO,IAAIoR,aAAc,GACxCxf,KAAK2Z,MAAM,GACJ3Z,KAAKoO,IAAI0P,4BAEhB9d,KAAK2Z,MAAM,GACJ3Z,KAAKoO,IAAIoR,kBAIpB9F,GAAK1Z,KAAKiZ,OAKd,OAAOjZ,MAAKoO,IAAI0P,2BAGlByB,iBAAkB,WAGhB,GAFAvf,KAAKud;AACL7D,GAAK1Z,KAAKiZ,QACA,KAANS,GAGF,MAFA1Z,MAAK2Z,MAAM,GACX3Z,KAAKyZ,MAAM,iBACJzZ,KAAKoO,IAAIyP,UACX,IAAW,MAAPnE,GAAY,CACrB,GAAqB,MAAjB1Z,KAAKiZ,QAMP,MALAjZ,MAAKiZ,QACDjZ,KAAKsd,kBACPtd,KAAKyZ,MAAM,2BAEbzZ,KAAK2Z,MAAM,GACJ3Z,KAAKoO,IAAIyP,UAEhB7d,MAAK2Z,MAAM,OAGb3Z,MAAK2Z,MAAM,EAEZ,OAAO3Z,MAAKoO,IAAIyP,YAGnB4B,kBAAmB,WAEjB,GAAI/F,GAAK1Z,KAAKiZ,OACd,IAAW,MAAPS,EAAY,CAEd,GADAA,EAAK1Z,KAAKiZ,QACC,MAAPS,EAEF,MADA1Z,MAAKyZ,MAAM,0BACJzZ,KAAKoO,IAAIkR,0BACX,IAAItf,KAAKsd,iBAAkB,CAChC,GAAIlP,GAAMpO,KAAKuf,kBACf,OAAOnR,QAEJ,IAAW,MAAPsL,GACT,GAAiC,MAA7B1Z,KAAKgE,OAAOhE,KAAKkE,QAEnB,MADAlE,MAAKyZ,MAAM,mBACJzZ,KAAKoO,IAAIoR,iBAEb,IAAW,MAAP9F,EAET,MADA1Z,MAAKkb,WACE,GAIT,MAAMlb,KAAKkE,OAASlE,KAAKkZ,MAAM,CAC7B,GAAW,OAAPQ,EACF1Z,KAAKiZ,YACA,CAAA,GAAW,MAAPS,EAAY,CACrB1Z,KAAK2Z,MAAM,GACX3Z,KAAKkb,WACLlb,KAAKua,YAAY,IAAK,EACtB,OACK,GAAW,MAAPb,EAAY,CAErB,GADAA,EAAK1Z,KAAKiZ,QACC,MAAPS,EAEF,MADA1Z,MAAKyZ,MAAM,0BACPzZ,KAAKoZ,OAAO7Z,OAAS,GACvBS,KAAKua,YAAYva,KAAKoO,IAAIkR,2BAA4B,GACtDtf,KAAK2Z,MAAM,GACJ3Z,KAAKoO,IAAI0P,2BAET9d,KAAKoO,IAAIkR;AAEb,GAAItf,KAAKsd,iBAAkB,CAEhC,GAAIsB,GAAW5e,KAAKkE,OAChBuW,EAAOza,KAAKuf,kBAChB,OAAIvf,MAAKoZ,OAAO7Z,OAASS,KAAKkE,OAAS0a,EAAW,GAChD5e,KAAKua,YAAYE,EAAMza,KAAKkE,OAAS0a,EAAW,GAChD5e,KAAK2Z,MAAM3Z,KAAKkE,OAAS0a,EAAW,GAC7B5e,KAAKoO,IAAI0P,2BAETrD,EAGXza,KAAK2Z,MAAM,OACN,IAAW,MAAPD,EAAY,CAErB,GADAA,EAAK1Z,KAAKiZ,QACC,MAAPS,EAGF,MADA1Z,MAAKyZ,MAAM,mBACPzZ,KAAKoZ,OAAO7Z,OAAS,GACvBS,KAAKua,YAAYva,KAAKoO,IAAIoR,aAAc,GACxCxf,KAAK2Z,MAAM,GACJ3Z,KAAKoO,IAAI0P,4BAEhB9d,KAAK2Z,MAAM,GACJ3Z,KAAKoO,IAAIoR,aAGpBxf,MAAK2Z,MAAM,IAEbD,EAAK1Z,KAAKiZ,QAEZ,MAAOjZ,MAAKoO,IAAI0P,2BAIlB4B,sBAAuB,WAErB,GAAIhG,GAAK1Z,KAAKiZ,OACd,IAAW,MAAPS,EAAY,CAEd,GADAA,EAAK1Z,KAAKiZ,QACC,MAAPS,EAEF,MADA1Z,MAAKyZ,MAAM,0BACJzZ,KAAKoO,IAAIkR,0BACX,IAAItf,KAAKsd,iBAAkB,CAChC,GAAIlP,GAAMpO,KAAKuf,kBACf,OAAOnR,QAEJ,IAAW,MAAPsL,GACT,GAAiC,MAA7B1Z,KAAKgE,OAAOhE,KAAKkE,QAEnB,MADAlE,MAAKyZ,MAAM,mBACJzZ,KAAKoO,IAAIoR,iBAEb,IAAW,MAAP9F,EAET,MADA1Z,MAAKkb,WACE,GAIT,MAAMlb,KAAKkE,OAASlE,KAAKkZ,MAAM,CAC7B,GAAW,OAAPQ,EACF1Z,KAAKiZ,YACA,CAAA,GAAW,MAAPS,EAAY,CACrB1Z,KAAK2Z,MAAM,GACX3Z,KAAKkb,WACLlb,KAAKua,YAAY,IAAK;AACtB,MACK,GAAW,MAAPb,EAAY,CAErB,GADAA,EAAK1Z,KAAKiZ,QACC,MAAPS,EAEF,MADA1Z,MAAKyZ,MAAM,0BACPzZ,KAAKoZ,OAAO7Z,OAAS,GACvBS,KAAKua,YAAYva,KAAKoO,IAAIkR,2BAA4B,GACtDtf,KAAK2Z,MAAM,GACJ3Z,KAAKoO,IAAI0P,2BAET9d,KAAKoO,IAAIkR,0BAEb,IAAItf,KAAKsd,iBAAkB,CAEhC,GAAIsB,GAAW5e,KAAKkE,OAChBuW,EAAOza,KAAKuf,kBAChB,OAAIvf,MAAKoZ,OAAO7Z,OAASS,KAAKkE,OAAS0a,EAAW,GAChD5e,KAAKua,YAAYE,EAAMza,KAAKkE,OAAS0a,EAAW,GAChD5e,KAAK2Z,MAAM3Z,KAAKkE,OAAS0a,EAAW,GAC7B5e,KAAKoO,IAAI0P,2BAETrD,EAGXza,KAAK2Z,MAAM,OACN,IAAW,MAAPD,EAAY,CAErB,GADAA,EAAK1Z,KAAKiZ,QACC,MAAPS,EAGF,MADA1Z,MAAKyZ,MAAM,mBACPzZ,KAAKoZ,OAAO7Z,OAAS,GACvBS,KAAKua,YAAYva,KAAKoO,IAAIoR,aAAc,GACxCxf,KAAK2Z,MAAM,GACJ3Z,KAAKoO,IAAI0P,4BAEhB9d,KAAK2Z,MAAM,GACJ3Z,KAAKoO,IAAIoR,aAGpBxf,MAAK2Z,MAAM,IAEbD,EAAK1Z,KAAKiZ,QAEZ,MAAOjZ,MAAKoO,IAAI0P,iCAId6B,IAAI,SAASphB,EAAQkB,EAAOJ,GAMlCI,EAAOJ,SACLme,SAAU,WACR,GAAIhT,GAAQxK,KAAKoZ,OAAOzU,cACpBib,EAAK5f,KAAK8O,SAAStE,EACvB,KAAKoV,EACH,GAAc,UAAVpV,EACExK,KAAK+Z,SAAS,UAChB/Z,KAAKma,QAAQ,GACbyF,EAAK5f,KAAKoO,IAAIyR,cAEdD,EAAK5f,KAAKoO,IAAI0R,YAIhB,IADAF,EAAK5f,KAAKoO,IAAIoP;AACA,MAAVhT,GAA2B,MAAVA,EAAe,CAClC,GAAIkP,GAAK1Z,KAAKiZ,MAAM,EACpB,IAAW,MAAPS,EACF,MAAO1Z,MAAKoe,kBACP,IAAW,MAAP1E,EACT,MAAO1Z,MAAKme,4BAEZne,MAAK2Z,MAAM,GAKnB,MAAOiG,IAGT1B,cAAe,WACb,GAAIxE,GAAK1Z,KAAKgE,OAAOhE,KAAKkE,OAAS,GAC/B6b,EAAK/f,KAAKggB,eAAetG,EAC7B,OAAIqG,GACKA,EAAGte,MAAMzB,SAETA,KAAKoZ,QAIhB4G,gBACEC,EAAK,WAEH,MADAjgB,MAAKkE,SACDlE,KAAKsd,kBACPtd,KAAKkE,SACLlE,KAAKud,gBACEvd,KAAKoO,IAAIyP,aAEhB7d,KAAKkE,SACE,MAGXgc,IAAK,WACH,GAAIC,GAAQngB,KAAKgE,OAAOhE,KAAKkE,OAC7B,OAAc,MAAVic,GACFngB,KAAKyZ,MAAM,2BAA2BR,QAC/BjZ,KAAKoO,IAAIiP,mBACG,MAAV8C,GACTngB,KAAKiZ,QACEjZ,KAAKoO,IAAIgS,OACG,MAAVD,GACTngB,KAAKiZ,QACEjZ,KAAKoO,IAAIiS,eAEX,KAETC,KAAM,WACJ,MAAOtgB,MAAKoO,IAAImS,gBAElBC,IAAK,WACH,MAAiC,MAA7BxgB,KAAKgE,OAAOhE,KAAKkE,SACnBlE,KAAKiZ,QACEjZ,KAAKoO,IAAIqS,aAEX,KAETC,IAAK,WACH,MAAiC,MAA7B1gB,KAAKgE,OAAOhE,KAAKkE,SACnBlE,KAAKiZ,QACEjZ,KAAKoO,IAAIuS,gBAET,KAGXC,IAAK,WACH,GAAIC,GAAU7gB,KAAKkE,MAKnB,IAJAlE,KAAKiZ,QACDjZ,KAAK0e,eACP1e,KAAK8gB,mBAAmB7H,QAEtBjZ,KAAKsd,iBAAkB,CACzB,GAAIyD,GAAQ/gB,KAAKoZ,OAAO7Z;AACxBS,KAAKud,eACL,IAAIyD,GAAYhhB,KAAKoZ,OAAOnV,UAAU8c,EAAQ,GAAGpc,cAC7Csc,EAASjhB,KAAK8X,aAAakJ,EAC/B,IAAIC,IACFjhB,KAAKiZ,QACDjZ,KAAK0e,eACP1e,KAAK8gB,mBAAmB7H,QAEW,MAAjCjZ,KAAKgE,OAAOhE,KAAKkE,OAAS,IAC5B,MAAO+c,GAMb,MADAjhB,MAAK2Z,MAAM3Z,KAAKkE,OAAS2c,GAClB,KAETK,IAAK,WACH,GAAIf,GAAQngB,KAAKgE,OAAOhE,KAAKkE,OAC7B,OAAc,MAAVic,GACFngB,KAAKiZ,QACEjZ,KAAKoO,IAAI+S,gBACG,MAAVhB,EAC4B,MAAjCngB,KAAKgE,OAAOhE,KAAKkE,OAAS,IAC5BlE,KAAKma,QAAQ,GACNna,KAAKoO,IAAIgT,iBAEhBphB,KAAKiZ,QACEjZ,KAAKoO,IAAIiT,YAGb,KAETC,IAAK,WACH,GAAInB,GAAQngB,KAAKgE,OAAOhE,KAAKkE,OAC7B,OAAc,MAAVic,GACFngB,KAAKiZ,QACEjZ,KAAKoO,IAAImT,OACG,MAAVpB,GACTngB,KAAKiZ,QACEjZ,KAAKoO,IAAIoT,cAEX,KAETC,IAAK,WACH,MAAiC,MAA7BzhB,KAAKgE,OAAOhE,KAAKkE,QACkB,MAAjClE,KAAKgE,OAAOhE,KAAKkE,OAAS,IAC5BlE,KAAKma,QAAQ,GACNna,KAAKoO,IAAIsT,qBAEhB1hB,KAAKiZ,QACEjZ,KAAKoO,IAAIuT,gBAGb,KAETC,IAAK,WACH,MAAiC,MAA7B5hB,KAAKgE,OAAOhE,KAAKkE,SACnBlE,KAAKiZ,QACEjZ,KAAKoO,IAAIyT,YAEX,KAETC,IAAK,WACH,GAAI3B,GAAQngB,KAAKgE,OAAOhE,KAAKkE,OAC7B,OAAc,MAAVic,GACFA,EAAQngB,KAAKgE,OAAOhE,KAAKkE,OAAS,GACpB,MAAVic,GACFngB,KAAKma,QAAQ,GACNna,KAAKoO,IAAI2T,YACG,MAAV5B,GACLngB,KAAKwe,aACAxe,KAAKoO,IAAI4Q,iBAGpBhf,KAAKiZ;AACEjZ,KAAKoO,IAAI4T,OACG,MAAV7B,GACTngB,KAAKiZ,QAC4B,MAA7BjZ,KAAKgE,OAAOhE,KAAKkE,SACnBlE,KAAKiZ,QACEjZ,KAAKoO,IAAI6T,aAETjiB,KAAKoO,IAAI8T,uBAEC,MAAV/B,GACTngB,KAAKiZ,QACEjZ,KAAKoO,IAAIuT,gBAEX,KAETQ,IAAK,WACH,GAAIhC,GAAQngB,KAAKgE,OAAOhE,KAAKkE,OAC7B,OAAc,MAAVic,GACFngB,KAAKiZ,QACEjZ,KAAKoO,IAAIgU,uBACG,MAAVjC,GACTA,EAAQngB,KAAKgE,OAAOhE,KAAKkE,OAAS,GACpB,MAAVic,GACFngB,KAAKma,QAAQ,GACNna,KAAKoO,IAAIiU,aAEhBriB,KAAKiZ,QACEjZ,KAAKoO,IAAIkU,OAGb,KAETC,IAAK,WACH,GAAIpC,GAAQngB,KAAKgE,OAAOhE,KAAKkE,OAC7B,OAAc,MAAVic,GACFngB,KAAKiZ,QACEjZ,KAAKoO,IAAIoU,aACE,MAAVrC,GACRngB,KAAKiZ,QAC4B,MAA7BjZ,KAAKgE,OAAOhE,KAAKkE,SACnBlE,KAAKiZ,QACEjZ,KAAKoO,IAAIqU,aAETziB,KAAKoO,IAAIsU,OAGb,KAETC,IAAK,WACH,GAAIxC,GAAQngB,KAAKgE,OAAOhE,KAAKkE,OAC7B,OAAc,MAAVic,GACFngB,KAAKiZ,QACEjZ,KAAKoO,IAAIwU,gBACG,MAAVzC,GAAkD,MAAjCngB,KAAKgE,OAAOhE,KAAKkE,OAAS,IACpDlE,KAAKma,QAAQ,GACNna,KAAKoO,IAAIyU,YAEX,KAETC,IAAK,WACH,MAAiC,MAA7B9iB,KAAKgE,OAAOhE,KAAKkE,SACnBlE,KAAKiZ,QACEjZ,KAAKoO,IAAI2U,aAEX,KAETC,IAAK,WACH,GAAI7C,GAAQngB,KAAKgE,OAAOhE,KAAKkE,OAC7B,OAAc,MAAVic,GACFngB,KAAKiZ,QACEjZ,KAAKoO,IAAI6U,aACG,MAAV9C,GACTngB,KAAKiZ,QACEjZ,KAAKoO,IAAI8U,eAEX;EAETC,IAAK,WACH,GAAIhD,GAAQngB,KAAKgE,OAAOhE,KAAKkE,OAC7B,OAAc,MAAVic,GACFngB,KAAKiZ,QACEjZ,KAAKoO,IAAIgV,YACG,MAAVjD,GACTngB,KAAKiZ,QACEjZ,KAAKoO,IAAIiV,cAEX,KAETC,IAAK,WACH,MAAiC,MAA7BtjB,KAAKgE,OAAOhE,KAAKkE,SACnBlE,KAAKiZ,QACEjZ,KAAKoO,IAAImV,aAEX,YAKPC,IAAI,SAASjlB,EAAQkB,EAAOJ,GAMjC,GAAIgP,GAAS,4BAEd5O,GAAOJ,SAGLyd,OAAQ,WACN,GAAIpD,GAAK1Z,KAAKgE,OAAOyf,WAAWzjB,KAAKkE,OAAS,EAC9C,OAAOwV,GAAK,IAAMA,EAAK,IAIzBmF,SAAU,WACR,GAAInF,GAAK1Z,KAAKgE,OAAOyf,WAAWzjB,KAAKkE,OAAS,EAC9C,OAAQwV,GAAK,IAAMA,EAAK,KAClBA,EAAK,IAAMA,EAAK,IACV,KAAPA,GACCA,EAAK,IAAMA,EAAK,IACjBA,EAAK,KAKZ4D,eAAgB,WACd,GAAI5D,GAAK1Z,KAAKgE,OAAOyf,WAAWzjB,KAAKkE,OAAS,EAC9C,OAAQwV,GAAK,IAAMA,EAAK,KAClBA,EAAK,IAAMA,EAAK,IACV,KAAPA,GACCA,EAAK,KAMb6D,cAAe,WACb,KAAMvd,KAAKkE,OAASlE,KAAKkZ,MAEvB,GADAlZ,KAAKiZ,SACAjZ,KAAK6e,WAAY,CACpB7e,KAAK2Z,MAAM,EACX,OAGJ,MAAO3Z,OAIT+d,SAAU,WACR,GAAIrE,GAAK1Z,KAAKgE,OAAOhE,KAAKkE,OAAS,EACnC,OAAOmK,GAAOqV,QAAQhK,MAAQ,GAGhCiK,WAAY,WACV,GAAIjK,GAAK1Z,KAAKgE,OAAOhE,KAAKkE,OAAS,EACnC,OAAc,OAAPwV,GAAsB,OAAPA,GAGxBsC,cAAe,WACb,GAAItC,GAAK1Z,KAAKgE,OAAOhE,KAAKkE,OAAS,EACnC,OAAc,MAAPwV,GAAqB,OAAPA,GAAsB,OAAPA,GAAsB,OAAPA,GAGrDgF,YAAa;AACX,GAAIhF,GAAK1Z,KAAKgE,OAAOhE,KAAKkE,OAAS,EACnC,OAAc,MAAPwV,GAAqB,OAAPA,GAGvBoH,iBAAkB,WAChB,KAAM9gB,KAAKkE,OAASlE,KAAKkZ,MAEvB,GADAlZ,KAAKiZ,SACAjZ,KAAK0e,cAAe,CACvB1e,KAAK2Z,MAAM,EACX,OAGJ,MAAO3Z,OAGT2c,OAAQ,WACN,GAAIjD,GAAK1Z,KAAKgE,OAAOyf,WAAWzjB,KAAKkE,OAAS,EAC9C,OAAQwV,GAAK,IAAMA,EAAK,IAAQA,EAAK,IAAMA,EAAK,IAAQA,EAAK,IAAMA,EAAK,WAItEkK,IAAI,SAASrlB,EAAQkB,EAAOJ,GAUlC,QAASwkB,GAASnlB,GAChB,MAAY,KAALA,GAAiB,KAALA,IAAaolB,MAAMC,WAAWrlB,KAAOslB,SAAStlB,GAcnE,GAAI2E,GAAS,SAASE,EAAO0gB,GAC3BjkB,KAAKuD,MAAQA,EACbvD,KAAKikB,IAAMA,EACXjkB,KAAKoO,IAAM7K,EAAM6K,IACjBpO,KAAKuO,IAAMhL,EAAMgL,IAEjBvO,KAAKkkB,kBACLlkB,KAAKmkB,WAAY,EACjBnkB,KAAKwK,MAAQ,KACbxK,KAAKokB,KAAO,KACZpkB,KAAKqkB,OAAQ,EACbrkB,KAAKskB,YAAa,EAClBtkB,KAAKukB,gBAAiB,EACtBvkB,KAAKwkB,WAAY,EACjBxkB,KAAKykB,WACLzkB,KAAK0kB,SACHC,QACE3kB,KAAKoO,IAAI+P,2BACTne,KAAKoO,IAAI4Q,gBACThf,KAAKoO,IAAI6O,UACTjd,KAAKoO,IAAI4O,UACThd,KAAKoO,IAAIoP,SACTxd,KAAKoO,IAAIiJ,QAAQ,IACjBrX,KAAKoO,IAAIY,UACThP,KAAKoO,IAAIc,UACTlP,KAAKoO,IAAIgB,SACTpP,KAAKoO,IAAIkB,WACTtP,KAAKoO,IAAIoB,OACTxP,KAAKoO,IAAIsB,OACT1P,KAAKoO,IAAIwB,MACT5P,KAAKoO,IAAI0B,OACT,IACA,KACA,KACA,IACA9P,KAAKoO,IAAImS,gBAEXqE,eACI5kB,KAAKoO,IAAIY,UACThP,KAAKoO,IAAIc,UACTlP,KAAKoO,IAAIgB,SACTpP,KAAKoO,IAAIkB,WACTtP,KAAKoO,IAAIoB,OACTxP,KAAKoO,IAAIsB,OACT1P,KAAKoO,IAAIwB,MACT5P,KAAKoO,IAAI0B;AAEb+U,gBACE7kB,KAAKoO,IAAI4I,SACThX,KAAKoO,IAAIwI,UACT5W,KAAKoO,IAAI0I,YACT9W,KAAKoO,IAAIkI,SACTtW,KAAKoO,IAAIoI,WACTxW,KAAKoO,IAAIsI,SAEXoO,UACE9kB,KAAKoO,IAAIyP,WACT,IACA7d,KAAKoO,IAAImS,eACTvgB,KAAKoO,IAAIoP,SACTxd,KAAKoO,IAAIkI,UAEXyO,KACE,IACA/kB,KAAKoO,IAAIkQ,YACTte,KAAKuO,IACLvO,KAAKoO,IAAIgO,eAEX4I,MACE,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IACxBhlB,KAAKoO,IAAIgJ,OACTpX,KAAKoO,IAAIuG,QACT3U,KAAKoO,IAAImT,MACTvhB,KAAKoO,IAAIgS,MACTpgB,KAAKoO,IAAIqG,MACTzU,KAAKoO,IAAI4H,QACThW,KAAKoO,IAAI8H,QACTlW,KAAKoO,IAAI6G,UACTjV,KAAKoO,IAAI+G,eACTnV,KAAKoO,IAAIgH,UACTpV,KAAKoO,IAAIkH,eACTtV,KAAKoO,IAAI2G,OACT/U,KAAKoO,IAAI4J,WACThY,KAAKoO,IAAI+J,cACTnY,KAAKoO,IAAImK,cACTvY,KAAKoO,IAAIqK,aACTzY,KAAKoO,IAAIuK,cACT3Y,KAAKoO,IAAIyK,YACT7Y,KAAKoO,IAAI2K,aACT/Y,KAAKoO,IAAI4B,OACThQ,KAAKoO,IAAI2F,QACT/T,KAAKoO,IAAI0R,QACT9f,KAAKoO,IAAIkI,SACTtW,KAAKoO,IAAI+B,WAETnQ,KAAKoO,IAAIyP,WACT,IACA7d,KAAKoO,IAAImS,eACTvgB,KAAKoO,IAAIoP,SAETxd,KAAKoO,IAAIoP,SACTxd,KAAKoO,IAAI+P,2BACTne,KAAKoO,IAAI4Q,gBACThf,KAAKoO,IAAI6O,UACTjd,KAAKoO,IAAI4O,UACThd,KAAKoO,IAAIiJ,QAAQ,IACjBrX,KAAKoO,IAAIY,UACThP,KAAKoO,IAAIc,UACTlP,KAAKoO,IAAIgB,SACTpP,KAAKoO,IAAIkB,WACTtP,KAAKoO,IAAIoB,OACTxP,KAAKoO,IAAIsB,OACT1P,KAAKoO,IAAIwB,MACT5P,KAAKoO,IAAI0B;EAQfzM,GAAO7B,UAAUyjB,aAAe,SAASza,GACvC,MAAKqZ,GAASrZ,GAGRA,GAASxK,KAAKuO,IAAY,wBACvBvO,KAAKuD,MAAM4K,OAAOE,OAAO6W,OAAO1a,GAHhC,IAAMA,EAAQ,KAUzBnH,EAAO7B,UAAU2jB,MAAQ,SAAShmB,GAChCa,KAAKolB,WACLplB,KAAKqlB,kBAAoB,IACzBrlB,KAAKuD,MAAMyV,SAAS7Z,GACpBa,KAAKuD,MAAMkL,eAAiBzO,KAAKskB,WACjCtkB,KAAKT,OAASS,KAAKuD,MAAMS,OAAOzE,OAChCS,KAAKslB,WAAY,CACjB,IAAIC,GAAUvlB,KAAKikB,IAAI9gB,QAAQ,UAAWnD,MACtCwlB,IAEJ,KADAxlB,KAAKylB,mBACCzlB,KAAKwK,OAASxK,KAAKuO,KAAK,CAC5B,GAAInK,GAAOpE,KAAK0lB,YACH,QAATthB,GAA0BuhB,SAATvhB,IACf/C,MAAMiK,QAAQlH,GAChBohB,EAASA,EAAO/kB,OAAO2D,GAEvBohB,EAAOjkB,KAAK6C,IAIlB,MAAOmhB,GAAQC,EAAQxlB,KAAKolB,UAM9B/hB,EAAO7B,UAAUokB,WAAa,SAASrb,EAASsb,EAAWC,EAAQtb,GACjE,IAAKxK,KAAKukB,eACR,KAAM,IAAIrlB,OAAMqL,EAGlB,IAAInG,GAAOpE,KAAKikB,IAAI9gB,QAAQ,QAASnD,MACnCuK,EAASC,EAAOxK,KAAKuD,MAAMC,OAAOC,WAAYqiB,EAGhD,OADA9lB,MAAKolB,QAAQ7jB,KAAK6C,GACXA,GAMTf,EAAO7B,UAAUukB,MAAQ,SAASD,GAChC,GAAIE,GAAM,4BAEV,IADAxb,MAAQxK,KAAKilB,aAAajlB,KAAKwK,OAC3BxK,KAAKwK,QAAUxK,KAAKuO,IAAK,CAC3B,GAAIsV,EAAS7jB,KAAKwK,OAAQ,CACxB,GAAIyb,GAASjmB,KAAKga,MACdiM,GAAO1mB,OAAS,KAClB0mB,EAASA,EAAOhiB,UAAU,EAAG,GAAK,OAEpCuG,MAAQ,IAAKyb,EAAO,MAAOzb,MAAM,IAEnCwb,GAAO,gBAAkBxb,MAE3B,GAAIqb,GAAY,EAQhB,OAPIC,KAAWzkB,MAAMiK,QAAQwa,MACvBjC,EAASiC,IAA6B,IAAlBA,EAAOvmB,UAC7BsmB,EAAY,eAAiB7lB,KAAKilB,aAAaa;AAEjDE,GAAOH,GAET7lB,KAAKwK,QAAUxK,KAAKuO,IACbvO,KAAK4lB,WACVI,EAAM,YAAchmB,KAAKuD,MAAMC,OAAOC,WACtCoiB,EACAC,EACAtb,QAOJnH,EAAO7B,UAAU4C,KAAO,SAAS5B,GAC/B,MAAOxC,MAAKikB,IAAI9gB,QAAQX,EAAMxC,OAMhCqD,EAAO7B,UAAU0kB,qBAAuB,WAYtC,MAXmB,MAAflmB,KAAKwK,OACPxK,KAAKylB,mBACDzlB,KAAKwK,QAAUxK,KAAKoO,IAAIkQ,aAE1Bte,KAAKylB,oBAEEzlB,KAAKwK,QAAUxK,KAAKoO,IAAIkQ,YACjCte,KAAKylB,mBACIzlB,KAAKwK,QAAUxK,KAAKoO,IAAIgO,eAAiBpc,KAAKwK,QAAUxK,KAAKuO,KACtEvO,KAAK+lB,MAAM,KAEN/lB,KAIT,IAAImmB,IAAe,cAAe,0BAClC9iB,GAAO7B,UAAU4kB,QAAU,WAGzB,IAAK,GADD3b,GADA4b,GAAQ,GAAKnnB,QAASmnB,MAAMC,MAAM,MAE7BpiB,EAAS,EAAGA,EAASmiB,EAAM9mB,OAAQ2E,IAAW,CACrDuG,EAAO4b,EAAMniB,GAAQqiB,MAErB,KAAI,GADAC,IAAQ,EACJxnB,EAAI,EAAGA,EAAImnB,EAAY5mB,OAAQP,IACrC,GAAIyL,EAAKxG,UAAU,EAAG,EAAIkiB,EAAYnnB,GAAGO,UAAY4mB,EAAYnnB,GAAI,CACnEwnB,GAAQ,CACR,OAGJ,IAAKA,EACH,MAYJ,MARAC,SAAQC,IACN,QACE1mB,KAAKuD,MAAMC,OAAOC,WAClB,MACAzD,KAAKilB,aAAajlB,KAAKwK,OACvB,IAAMxK,KAAKuD,MAAM6V,OAAS,SAChB3O,GAEPzK,MAgBTqD,EAAO7B,UAAUskB,OAAS,SAAStb,GACjC,GAAInJ,MAAMiK,QAAQd,IAChB,GAAIA,EAAMkZ,QAAQ1jB,KAAKwK,UAAW,EAEhC,MADAxK,MAAK+lB,MAAMvb,IACJ,MAEJ,IAAIxK,KAAKwK,OAASA,EAEvB,MADAxK,MAAK+lB,MAAMvb,IACJ,CAET,OAAOxK,OAOTqD,EAAO7B,UAAUwY,KAAO;AACtB,MAAOha,MAAKuD,MAAM6V,QAIpB/V,EAAO7B,UAAUiZ,KAAO,WAStB,MARIza,MAAKqkB,OACPrkB,KAAKomB,UACLpmB,KAAKqkB,OAAQ,EACbrkB,KAAKylB,mBAAmBkB,iBACxB3mB,KAAKqkB,OAAQ,GAEbrkB,KAAKylB,mBAAmBkB,iBAEnB3mB,MAITqD,EAAO7B,UAAUmlB,eAAiB,WAEhC,IADI3mB,KAAKqkB,OAAOrkB,KAAKomB,UACfpmB,KAAKwK,QAAUxK,KAAKoO,IAAIuM,WAAa3a,KAAKwK,QAAUxK,KAAKoO,IAAIwM,eAEjE5a,KAAKylB,kBAEP,OAAOzlB,OAITqD,EAAO7B,UAAUikB,iBAAmB,WAQlC,MAPAzlB,MAAKokB,MACHpkB,KAAKuD,MAAMC,OAAOC,WAClBzD,KAAKuD,MAAMC,OAAOE,aAClB1D,KAAKuD,MAAMW,QAEblE,KAAKwK,MAAQxK,KAAKuD,MAAMiX,OAASxa,KAAKuO,IAClCvO,KAAKqkB,OAAOrkB,KAAKomB,UACdpmB,MAMTqD,EAAO7B,UAAUolB,GAAK,SAAS/d,GAC7B,MAAIxH,OAAMiK,QAAQzC,GACTA,EAAK6a,QAAQ1jB,KAAKwK,UAAW,EAE7BxK,KAAK0kB,QAAQ7b,GAAM6a,QAAQ1jB,KAAKwK,SAAU,GAKrDnH,EAAO7B,UAAUqlB,WAAa,WAC5B,GAAIxiB,GAASrE,KAAKwK,KAKlB,OAJIqZ,GAASxf,KACXA,GAAUA,EAAQrE,KAAKga,OAAQha,KAAKuD,MAAMC,OAAOC,aAEnDzD,KAAKya,OACEpW,GASThB,EAAO7B,UAAUslB,UAAY,SAASC,EAAMC,EAAWC,GACrD,GAAI5iB,KAOJ,IALIrE,KAAKwK,OAASwc,IACZC,GAAwB5iB,EAAO9C,KAAK,IACxCvB,KAAKya,QAGe,kBAAX,IACT,EAEE,IADApW,EAAO9C,KAAKwlB,EAAKtlB,MAAMzB,UACnBA,KAAKwK,OAASwc,EAChB,YAEIhnB,KAAKya,OAAOjQ,OAASxK,KAAKuO;KAGlC,KADAlK,EAAO9C,KAAKvB,KAAK8lB,OAAOiB,GAAM/M,QACvBha,KAAKya,OAAOjQ,OAASxK,KAAKuO,KAC3BvO,KAAKwK,OAASwc,GAEdhnB,KAAKya,OAAOjQ,OAASuc,GACzB1iB,EAAO9C,KAAKvB,KAAKga,OAGrB,OAAO3V,KAMP9F,EAAQ,qBACRA,EAAQ,qBACRA,EAAQ,oBACRA,EAAQ,wBACRA,EAAQ,kBACRA,EAAQ,qBACRA,EAAQ,oBACRA,EAAQ,yBACRA,EAAQ,sBACRA,EAAQ,yBACRA,EAAQ,sBACRA,EAAQ,mBACRA,EAAQ,uBACRA,EAAQ,yBACRiG,QAAQ,SAAU4D,GAClB,IAAI,GAAIgT,KAAKhT,GACX/E,EAAO7B,UAAU4Z,GAAKhT,EAAIgT,KAI9B3b,EAAOJ,QAAUgE,IAEd6jB,oBAAoB,GAAGC,oBAAoB,GAAGC,sBAAsB,GAAGC,mBAAmB,GAAGC,uBAAuB,GAAGC,iBAAiB,GAAGC,oBAAoB,GAAGC,mBAAmB,GAAGC,wBAAwB,GAAGC,qBAAqB,GAAGC,wBAAwB,GAAGC,qBAAqB,GAAGC,kBAAkB,GAAGC,uBAAuB,KAAKC,IAAI,SAASzpB,EAAQkB,EAAOJ,GAM9W,GAAI4oB,GAAY,QACZC,EAAa,OAEjBzoB,GAAOJ,SAQL8oB,WAAY,WACV,GAAIrC,GAAS,KACThf,GAAY,EACZC,KACA1C,EAASrE,KAAKoE,KAAK6jB,EAOvB,IALIjoB,KAAK8lB,QAAQ9lB,KAAKoO,IAAIiJ,QAAS,MAAM7M,OAASxK,KAAKoO,IAAIiJ,QACzDrX,KAAKya,OAAOqL,OAAO,KAEnBhf,GAAY;AAEV9G,KAAKya,OAAOjQ,OAASsb,EACvB,KAAM9lB,KAAKwK,OAASxK,KAAKuO,MACvBxH,EAAMxF,KAAKvB,KAAKooB,wBACE,KAAdpoB,KAAKwK,SACPxK,KAAKya,OACDza,KAAKwK,QAAUsb,KAOzB,MADA9lB,MAAK8lB,OAAOhf,EAAY,IAAM,KAAK2T,OAC5BpW,EAAOyC,EAAWC,IAe3BqhB,qBAAsB,WACpB,GAAI/jB,GAASrE,KAAKoE,KAAK8jB,GACnB9d,EAAM,KACNtC,EAAQ,IACZ,IAAmB,MAAf9H,KAAKwK,MACP1C,EAAQ9H,KAAKya,OAAO4N,eAAc,GAAM,GAAO,OAC1C,CACL,GAAIC,GAAOtoB,KAAKuoB,WACZvoB,MAAKwK,QAAUxK,KAAKoO,IAAI+S,gBAC1B/W,EAAMke,EAEJxgB,EADwB,MAAtB9H,KAAKya,OAAOjQ,MACNxK,KAAKya,OAAO4N,eAAc,GAAM,GAAO,GAEvCroB,KAAKuoB,aAGfzgB,EAAQwgB,EAGZ,MAAOjkB,GAAO+F,EAAKtC,IAOrB0gB,gBAAiB,WACf,MAAkB,KAAdxoB,KAAKwK,OACFxK,KAAKuoB,mBAIVE,IAAI,SAASlqB,EAAQkB,EAAOJ,GAOlCI,EAAOJ,SAOLqpB,WAAY,SAASC,GACnB,GAAItkB,GAASrE,KAAKoE,KAAK,QACvBpE,MAAK8lB,OAAO9lB,KAAKoO,IAAI6F,SAClBwG,OACAqL,OAAO9lB,KAAKoO,IAAIoP,SAEnB,IAAIoL,GAAW5oB,KAAKga,OAChB6O,GAAc,EACdC,GAAiB,CAWrB,OATI9oB,MAAKya,OAAOjQ,OAASxK,KAAKoO,IAAIkG,YAChCuU,EAAc7oB,KAAKya,OAAOsO,uBAExB/oB,KAAKwK,OAASxK,KAAKoO,IAAImG,eACzBuU,EAAiB9oB,KAAKya,OAAOqM,UAC3B9mB,KAAK+oB,oBACL,MAGG1kB,EACLukB,EACCD,EACAE,EACAC,EACA9oB,KAAK8lB,OAAO,KAAKL,mBAAmBuD,oBASxCC,iBAAkB,WACjB,GAAI5kB,GAASrE,KAAKwK,KAClB,OAAInG,IAAUrE,KAAKoO,IAAIsI,SACrB1W,KAAKya;CACE,GACEpW,GAAUrE,KAAKoO,IAAIoI,YAC5BxW,KAAKya,OACE,GAEF,GAQRuO,gBAAiB,WAGhB,IAFA,GAAI3kB,MAEErE,KAAKwK,QAAUxK,KAAKuO,KAAsB,MAAfvO,KAAKwK,OAEpC,GAAIxK,KAAKwK,QAAUxK,KAAKoO,IAAIuM,UAK5B,GAAI3a,KAAKwK,QAAUxK,KAAKoO,IAAIwM,cAM5B,GAAI5a,KAAKwK,QAAUxK,KAAKoO,IAAIsH,MAA5B,CAQA,GAAI9M,GAAQ5I,KAAKkpB,mBAAkB,EAGnC,IAAIlpB,KAAKwK,QAAUxK,KAAKoO,IAAIiC,QAa5B,GALIrQ,KAAKwK,QAAUxK,KAAKoO,IAAIyG,QAC1B7U,KAAKya,OAAOqL,OAAO9lB,KAAKoO,IAAIyP,YAC5BjV,EAAM,GAAKA,EAAM,GAAK,GAGpB5I,KAAKwK,QAAUxK,KAAKoO,IAAIyP,WAAY,CAGtC,GAAIsL,GAAYnpB,KAAKopB,mBAAmBxgB,EACxC5I,MAAK8lB,OAAO,KAAKL,kBAEjB,KAAI,GAAIzmB,GAAI,EAAGA,EAAImqB,EAAU5pB,OAAQP,IAAK,CACxC,GAAIqqB,GAAWF,EAAUnqB,IACxBgB,KAAKspB,UAAYD,EAAS,GAAKA,GAAU9nB,KAAKqH,GAC/CvE,EAAO9C,KAAK8nB,QAGLrpB,MAAKwK,QAAUxK,KAAKoO,IAAI+B,WAGjC9L,EAAO9C,KAAKvB,KAAKupB,eAAc,EAAO3gB,KAKtCvE,EAAO9C,KACLvB,KAAK+lB,OACH/lB,KAAKoO,IAAIiC,QACTrQ,KAAKoO,IAAIyP,WACT7d,KAAKoO,IAAI+B,cAGbnQ,KAAKya,YAxCP,CACE,GAAI+O,GAAYxpB,KAAKypB,mBAAmB7gB,EACxC5I,MAAK8lB,OAAO,KAAKL,mBACjBphB,EAASA,EAAO5D,OAAO+oB,QAbvBnlB,GAASA,EAAO5D,OACdT,KAAKya,OAAOiP,gCAPdrlB,GAAO9C,KAAKvB,KAAK2pB,wBALjBtlB,GAAO9C,KAAKvB,KAAK4pB,eAkErB,OADA5pB,MAAK8lB,OAAO,KAAKL,mBACVphB,GAQR+kB,mBAAoB;AACnB,MAAOppB,MAAK8mB,UACV9mB,KAAK6pB,0BACL,MASHA,0BAA2B,WAC1B,GAAIxlB,GAASrE,KAAKoE,KAAK,OACnB5B,EAAOxC,KAAK8lB,OAAO9lB,KAAKoO,IAAIyP,YAAY7D,MAE5C,OADAha,MAAKya,OACc,MAAfza,KAAKwK,OAAgC,MAAfxK,KAAKwK,MACtBnG,EAAO7B,EAAM,MACG,MAAfxC,KAAKwK,MAENnG,EAAO7B,EAAMxC,KAAKya,OAAO8N,cAEhCvoB,KAAK8lB,QAAQ,IAAK,IAAK,MAChBzhB,EAAO7B,EAAM,QASvBinB,mBAAoB,SAAS7gB,GAC5B,MAAO5I,MAAK8lB,OAAO9lB,KAAKoO,IAAIiC,SACzBoK,OACAqM,UASC,WACE,GAAIziB,GAASrE,KAAKoE,KAAK,iBACnB5B,EAAOxC,KAAK8lB,OAAO9lB,KAAKoO,IAAIoP,UAAUxD,OACtClS,EAAS9H,KAAKya,OAAOqL,OAAO,KAAKrL,OAAO8N,WAC5C,OAAOlkB,GAAO7B,EAAMsF,EAAOc,IAC1B,MAWRsgB,kBAAmB,SAASY,GAC3B,GAAIzlB,KAAU,GAAI,GAAI,EACtB,IAAIrE,KAAK4mB,GAAG,kBAAmB,CAC7B,GAAImD,GAAM,EAAGC,EAAM,CACnB,GAAG,CACD,OAAOhqB,KAAKwK,OACV,IAAKxK,MAAKoO,IAAI4I,SAAc+S,EAAM,EAAGC,EAAM,CAAG,MAC9C,KAAKhqB,MAAKoO,IAAI0I,YAAciT,EAAM,EAAGC,EAAM,CAAG,MAC9C,KAAKhqB,MAAKoO,IAAIwI,UAAcmT,EAAM,EAAGC,EAAM,CAAG,MAC9C,KAAKhqB,MAAKoO,IAAIkI,SAAcyT,EAAM,EAAGC,EAAM,CAAG,MAC9C,KAAKhqB,MAAKoO,IAAIoI,WAAcuT,EAAM,EAAGC,EAAM,CAAG,MAC9C,KAAKhqB,MAAKoO,IAAIsI,QAAcqT,EAAM,EAAGC,EAAM,EAEzCF,IACS,GAAPC,GAAmB,GAAPC,GAEdhqB,KAAK8lB,QAAQ9lB,KAAKoO,IAAI4I,SAAUhX,KAAKoO,IAAI0I,cACzCkT,GAAM,GACU,GAAPD,GAAmB,GAAPC,IAErBhqB,KAAK+lB,QACLiE,GAAM,IAGN3lB,EAAO0lB,MAAS,EAElB/pB,KAAK+lB,QACIiE,KAAQ,IACjB3lB,EAAO0lB,GAAOC;OAEVhqB,KAAKya,OAAOmM,GAAG,mBAMzB,MAHIviB,GAAO,KAAM,IAAIA,EAAO,GAAK,GAC7BA,EAAO,KAAM,IAAIA,EAAO,GAAK,GAC7BA,EAAO,KAAM,IAAIA,EAAO,GAAK,GAC1BA,GAQR4lB,eAAgB,SAAStB,GACxB,GAAItkB,GAASrE,KAAKoE,KAAK,aACnB5B,EAAOxC,KAAK8lB,OAAO9lB,KAAKoO,IAAI+F,aAC7BsG,OACAqL,OAAO9lB,KAAKoO,IAAIoP,UAChBxD,OAEC6O,GAAc,CAOlB,OANI7oB,MAAKya,OAAOjQ,OAASxK,KAAKoO,IAAIkG,YAChCuU,EAAe7oB,KAAKya,OAAOqM,UACzB9mB,KAAK+oB,oBACL,MAGG1kB,EACL7B,EACEmmB,EACAE,EACA7oB,KAAK8lB,OAAO,KAAKrL,OAAOyP,wBAS7BA,oBAAqB,WAGpB,IAFA,GAAI7lB,MAEErE,KAAKwK,QAAUxK,KAAKuO,KAAsB,MAAfvO,KAAKwK,OAEpC,GAAIxK,KAAKwK,QAAUxK,KAAKoO,IAAIuM,UAK5B,GAAI3a,KAAKwK,QAAUxK,KAAKoO,IAAIwM,cAA5B,CAMA,GAAIhS,GAAQ5I,KAAKkpB,mBAAkB,EAGnC,IAAIlpB,KAAKwK,OAASxK,KAAKoO,IAAIiC,QAAS,CAClC,GAAImZ,GAAYxpB,KAAKypB,mBAAmB7gB,EACxC5I,MAAK8lB,OAAO,KAAKL,mBACjBphB,EAASA,EAAO5D,OAAO+oB,OAIpB,IAAIxpB,KAAKwK,QAAUxK,KAAKoO,IAAI+B,WAAY,CAC3C,GAAIga,GAASnqB,KAAKoqB,0BAA0B,IAC3CpqB,KAAKspB,UAAYa,EAAO,GAAKA,GAAQ5oB,KAAKqH,GAC3CvE,EAAO9C,KAAK4oB,GACZnqB,KAAK8lB,OAAO,KAAKL,uBAGjBphB,GAAO9C,KACLvB,KAAK+lB,OACH/lB,KAAKoO,IAAIiC,QACTrQ,KAAKoO,IAAI+B,cAGbnQ,KAAKya,WA5BL4P,SAAUrqB,KAAK2pB,uBALfU,SAAUrqB,KAAK4pB,cAqCnB,OADA5pB,MAAK8lB,OAAO,KAAKrL;AACVpW,GAQRimB,WAAY,SAAS3B,GACpB,GAAItkB,GAASrE,KAAKoE,KAAK,QACvBpE,MAAK8lB,OAAO9lB,KAAKoO,IAAIiG,SAClBoG,OACAqL,OAAO9lB,KAAKoO,IAAIoP,SAEnB,IAAIoL,GAAW5oB,KAAKga,OAClB6O,GAAc,EACdC,GAAiB,CAUnB,OATI9oB,MAAKya,OAAOjQ,OAASxK,KAAKoO,IAAIkG,YAChCuU,EAAc7oB,KAAKya,OAAOsO,uBAExB/oB,KAAKwK,OAASxK,KAAKoO,IAAImG,eACzBuU,EAAiB9oB,KAAKya,OAAOqM,UAC3B9mB,KAAK+oB,oBACL,MAGG1kB,EACLukB,EACAC,EACAC,EACA9oB,KAAK8lB,OAAO,KAAKrL,OAAOuO,oBAS3BU,yBAA0B,WAKzB,IAHA,GAAItlB,GAAOpE,KAAKoE,KAAK,OACjB5B,EAAOxC,KAAK+oB,sBACZ1kB,GAAUD,EAAK5B,IACE,MAAfxC,KAAKwK,OACTpG,EAAOpE,KAAKoE,KAAK,OACjB5B,EAAOxC,KAAKya,OAAOsO,sBACnB1kB,EAAO9C,KAAK6C,EAAK5B,GAEnB,IAAmB,MAAfxC,KAAKwK,MAAe,CAEtB,KAAMxK,KAAKya,QACU,MAAfza,KAAKwK,OACTnG,EAAO9C,KAAKvB,KAAKuqB,wBACjBvqB,KAAK8lB,OAAO,IAEd9lB,MAAK8lB,OAAO,KAAKL,uBAEjBzlB,MAAK8lB,OAAO,KAAKL,kBAEnB,OAAOphB,IAQRkmB,qBAAsB,WACrB,GAAInmB,GAAOpE,KAAKoE,KAAK,SACjBomB,EAASxqB,KAAK+oB,sBACd0B,GAAM,EACN/e,GAAS,EACT9C,GAAQ,CAiCZ,OA/BI5I,MAAKwK,QAAUxK,KAAKoO,IAAIuS,iBAC1B6J,GACE,SACA,MACAA,EACAxqB,KAAKya,OAAOqL,OAAO9lB,KAAKoO,IAAIoP,UAAUxD,QAExCha,KAAKya,QAGHza,KAAKwK,QAAUxK,KAAKoO,IAAIwH,aAC1B6U,EAAM;AACN/e,EAAS1L,KAAKya,OAAOsO,uBACZ/oB,KAAKwK,QAAUxK,KAAKoO,IAAIyE,MACjC4X,EAAM,KACFzqB,KAAKya,OAAOmM,GAAG,oBACjBhe,EAAQ5I,KAAKkpB,qBAEXlpB,KAAKwK,QAAUxK,KAAKoO,IAAIoP,UAC1B9R,EAAS1L,KAAKga,OACdha,KAAKya,QACI7R,KAAU,GAEnB5I,KAAK8lB,OAAO9lB,KAAKoO,IAAIoP,WAGvBxd,KAAK8lB,QACH9lB,KAAKoO,IAAIyE,KACT7S,KAAKoO,IAAIwH,cAGNxR,EAAKomB,EAAQC,EAAK/e,EAAQ9C,UAI/B8hB,IAAI,SAASnsB,EAAQkB,EAAOJ,GAMlCI,EAAOJ,SAILuqB,aAAc,WAGZ,IAFA,GAAIvlB,GAASrE,KAAKoE,KAAK,WACnB6U,GAASjZ,KAAKga,QACZha,KAAKylB,mBAAmBjb,QAAUxK,KAAKoO,IAAIuM,WAC/C1B,EAAM1X,KAAKvB,KAAKga,OAElB,OAAO3V,GAAO4U,IAKhB0Q,iBAAkB,WAChB,GAAItlB,GAASrE,KAAKoE,KAAK,OAAOpE,KAAKga,OAEnC,OADAha,MAAKylB,mBACEphB,SAILsmB,IAAI,SAASpsB,EAAQkB,EAAOJ,GAOlCI,EAAOJ,SAELkpB,UAAW,WACT,GAAID,GAAOtoB,KAAK4qB,gBAChB,QAAO5qB,KAAKwK,OAEV,IAAK,IAAK,MAAOxK,MAAKoE,KAAK,OAAO,IAAKkkB,EAAMtoB,KAAKya,OAAO8N,YACzD,KAAK,IAAK,MAAOvoB,MAAKoE,KAAK,OAAO,IAAKkkB,EAAMtoB,KAAKya,OAAO8N,YACzD,KAAK,IAAK,OAAQ,MAAO,IAAKD,EAAMtoB,KAAKya,OAAO8N,YAChD,KAAK,IAAK,OAAQ,MAAO,IAAKD,EAAMtoB,KAAKya,OAAO8N,YAChD,KAAK,IAAK,OAAQ,MAAO,IAAKD,EAAMtoB,KAAKya,OAAO8N,YAChD,KAAK,IAAK,OAAQ,MAAO,IAAKD,EAAMtoB,KAAKya,OAAO8N;AAChD,IAAK,IAAK,OAAQ,MAAO,IAAKD,EAAMtoB,KAAKya,OAAO8N,YAChD,KAAK,IAAK,OAAQ,MAAO,IAAKD,EAAMtoB,KAAKya,OAAO8N,YAChD,KAAK,IAAK,OAAQ,MAAO,IAAKD,EAAMtoB,KAAKya,OAAO8N,YAChD,KAAKvoB,MAAKoO,IAAIsU,MAAQ,OAAQ,MAAO,KAAM4F,EAAMtoB,KAAKya,OAAO8N,YAC7D,KAAKvoB,MAAKoO,IAAI4T,KAAQ,OAAQ,MAAO,KAAMsG,EAAMtoB,KAAKya,OAAO8N,YAC7D,KAAKvoB,MAAKoO,IAAIkU,KAAQ,OAAQ,MAAO,KAAMgG,EAAMtoB,KAAKya,OAAO8N,YAG7D,KAAKvoB,MAAKoO,IAAIiV,aACd,IAAKrjB,MAAKoO,IAAIqJ,aAAgB,OAAQ,OAAQ,IAAK6Q,EAAMtoB,KAAKya,OAAO8N,YAErE,KAAKvoB,MAAKoO,IAAI8U,cACd,IAAKljB,MAAKoO,IAAIuJ,cAAgB,OAAQ,OAAQ,IAAK2Q,EAAMtoB,KAAKya,OAAO8N,YAErE,KAAKvoB,MAAKoO,IAAIyJ,cAAoB,OAAQ,OAAQ,IAAKyQ,EAAMtoB,KAAKya,OAAO8N,YACzE,KAAKvoB,MAAKoO,IAAIgT,eAAoB,OAAQ,OAAQ,IAAKkH,EAAMtoB,KAAKya,OAAO8N,YACzE,KAAKvoB,MAAKoO,IAAIsT,mBAAoB,OAAQ,OAAQ,KAAM4G,EAAMtoB,KAAKya,OAAO8N,YAC1E,KAAKvoB,MAAKoO,IAAIiT,WAAoB,OAAQ,OAAQ,IAAKiH,EAAMtoB,KAAKya,OAAO8N,YACzE,KAAKvoB,MAAKoO,IAAIuT,eAAoB,OAAQ,OAAQ,KAAM2G,EAAMtoB,KAAKya,OAAO8N,YAC1E,KAAK,IAA2B,OAAQ,OAAQ,IAAKD,EAAMtoB,KAAKya,OAAO8N,YACvE,KAAK,IAA2B,OAAQ,OAAQ,IAAKD,EAAMtoB,KAAKya,OAAO8N;AAEvE,IAAKvoB,MAAKoO,IAAI8T,sBAAwB,OAAQ,OAAQ,KAAMoG,EAAMtoB,KAAKya,OAAO8N,YAC9E,KAAKvoB,MAAKoO,IAAIgU,sBAAwB,OAAQ,OAAQ,KAAMkG,EAAMtoB,KAAKya,OAAO8N,YAC9E,KAAKvoB,MAAKoO,IAAI6T,YAAwB,OAAQ,OAAQ,MAAOqG,EAAMtoB,KAAKya,OAAO8N,YAC/E,KAAKvoB,MAAKoO,IAAIuE,aAAwB,OAAQ,OAAQ,IAAK2V,EAAMtoB,KAAKya,OAAO8N,YAG7E,KAAKvoB,MAAKoO,IAAIyT,WAEZ,MAAO7hB,MAAKoE,KAAK,YACfkkB,EAAMtoB,KAAKya,OAAO8N,YAGtB,KAAK,IACH,GAAIsC,GAAU,IAKd,OAJ0B,MAAtB7qB,KAAKya,OAAOjQ,QACdqgB,EAAU7qB,KAAKuoB,aAEjBvoB,KAAK8lB,OAAO,KAAKrL,QACT,QAAS6N,EAAMuC,EAAS7qB,KAAKuoB,aAEzC,MAAOD,IASRsC,eAAgB,WAEf,OAAO5qB,KAAKwK,OAEV,IAAK,IACH,OAAQ,SAAUxK,KAAKya,OAAO8N,YAEhC,KAAK,IACH,GAAIlkB,GAASrE,KAAKoE,MAElB,OADApE,MAAKya,OAEHza,KAAKwK,QAAUxK,KAAKoO,IAAI6O,WACxBjd,KAAKwK,QAAUxK,KAAKoO,IAAI4O,WAGxB3Y,EAASA,EAAO,SAAU,IAAMrE,KAAKga,QACrCha,KAAKya,OACEpW,GAEAA,EAAO,QAAS,IAAKrE,KAAKuoB,YAGrC,KAAK,IACL,IAAK,IACL,IAAK,IACH,MAAOvoB,MAAKoE,KAAK,SAASpE,KAAKwK,MAAOxK,KAAKuoB,YAE7C,KAAK,IACH,GAAID,GAAOtoB,KAAKya,OAAO8N,WAIvB,OAHAvoB,MAAK8lB,OAAO,KAAKrL,OAGbza,KAAKwK,QAAUxK,KAAKoO,IAAIiP,kBACnBrd,KAAK8qB,8BAA8BxC,GAAM,GACvCtoB,KAAKwK,QAAUxK,KAAKoO,IAAIoR,cAA+B,MAAfxf,KAAKwK,MAC/CxK,KAAK+qB,oBAAoBzC,GACR,MAAftoB,KAAKwK,MAEPxK,KAAKoE,KAAK,QACfkkB,EAAMtoB,KAAKgrB,+BAGN1C;AAGX,IAAK,IAEH,GAAIjkB,GAASrE,KAAKoE,KAAK,SACnBkkB,EAAOtoB,KAAKya,OAAOwQ,qBAAqB,IAC5C,OAAO5mB,GAAOikB,EAEhB,KAAKtoB,MAAKoO,IAAIgJ,OACZ,GAAI/S,GAASrE,KAAKoE,KAAK,OACvBpE,MAAKya,OAAOqL,OAAO,KAAKrL,MACxB,IAAIyQ,GAAUlrB,KAAKslB,SAEdtlB,MAAKslB,YAAWtlB,KAAKslB,WAAY,EAKtC,KAAI,GAJA6F,GAAanrB,KAAKorB,uBAGlBC,GAAU,EACNrsB,EAAI,EAAGA,EAAImsB,EAAW5rB,OAAQP,IACpC,GAAsB,OAAlBmsB,EAAWnsB,GAAa,CAC1BqsB,GAAU,CACV,OAUJ,MAPKA,IACHrrB,KAAK4lB,WACH,gDAAkD5lB,KAAKuD,MAAMC,OAAOC,YAGxEzD,KAAK8lB,OAAO,KAAKrL,OAEZyQ,EAKI7mB,EAAO8mB,EAAY,OAJ1BnrB,KAAKslB,WAAY,EACjBtlB,KAAK8lB,OAAO,KAAKrL,OACVpW,EAAO8mB,EAAYnrB,KAAKuoB,aAKnC,KAAKvoB,MAAKoO,IAAIuG,QACZ,MAAO3U,MAAKoE,KAAK,SACfpE,KAAKya,OAAO8N,YAGhB,KAAKvoB,MAAKoO,IAAImT,MACZ,GAAI/e,GAAOxC,KAAKya,OAAO4N,eAAc,GAAO,GAAO,EACnD,QAAQ,MAAO7lB,GAAO,MAAO,IAAKA,GAAO,SAAU,IAErD,KAAKxC,MAAKoO,IAAIgS,MACZ,GAAI5d,GAAOxC,KAAKya,OAAO4N,eAAc,GAAO,GAAO,EACnD,QAAQ,MAAO7lB,GAAO,MAAO,IAAKA,GAAO,SAAU,IAErD,KAAKxC,MAAKoO,IAAIqG,MACZ,MAAOzU,MAAKya,OAAO6Q,eAErB,KAAKtrB,MAAKoO,IAAI4H,QACZ,GAAI3R,GAASrE,KAAKoE,KAAK,QACvBpE,MAAKya,OAAOqL,OAAO,KAAKrL,MACxB,IAAIrZ,GAAOpB,KAAK8mB,UAAU9mB,KAAKuoB,UAAW,IAE1C,OADAvoB,MAAK8lB,OAAO,KAAKrL,OACVpW,EAAOjD,EAEhB,KAAKpB,MAAKoO,IAAI8H;AACZ,GAAI7R,GAASrE,KAAKoE,KAAK,QACvBpE,MAAKya,OAAOqL,OAAO,KAAKrL,MACxB,IAAI8Q,GAAMvrB,KAAKuoB,WAEf,OADAvoB,MAAK8lB,OAAO,KAAKrL,OACVpW,GAAQknB,GAEjB,KAAKvrB,MAAKoO,IAAI6G,UACZ,MAAOjV,MAAKoE,KAAK,YACf,GAAO,EACPpE,KAAKya,OAAO8N,YAGhB,KAAKvoB,MAAKoO,IAAI+G,eACZ,MAAOnV,MAAKoE,KAAK,YACf,GAAM,EACNpE,KAAKya,OAAO8N,YAGhB,KAAKvoB,MAAKoO,IAAIgH,UACZ,MAAOpV,MAAKoE,KAAK,YACf,GAAO,EACPpE,KAAKya,OAAO8N,YAGhB,KAAKvoB,MAAKoO,IAAIkH,eACZ,MAAOtV,MAAKoE,KAAK,YACf,GAAM,EACNpE,KAAKya,OAAO8N,YAGhB,KAAKvoB,MAAKoO,IAAI2G,OACZ,GAAI1Q,GAASrE,KAAKoE,KAAK,OACvBpE,MAAKya,OAAOqL,OAAO,KAAKrL,MACxB,IAAI6N,GAAOtoB,KAAKuoB,WAEhB,OADAvoB,MAAK8lB,OAAO,KAAKrL,OACVpW,EAAOikB,EAEhB,KAAKtoB,MAAKoO,IAAI4J,WACZ,OAAQ,OAAQ,MAAOhY,KAAKya,OAAO8N,YAErC,KAAKvoB,MAAKoO,IAAI+J,cACZ,OAAQ,OAAQ,SAAUnY,KAAKya,OAAO8N,YAExC,KAAKvoB,MAAKoO,IAAImK,cACZ,OAAQ,OAAQ,SAAUvY,KAAKya,OAAO8N,YAExC,KAAKvoB,MAAKoO,IAAIqK,aACZ,OAAQ,OAAQ,QAASzY,KAAKya,OAAO8N,YAEvC,KAAKvoB,MAAKoO,IAAIuK,cACZ,OAAQ,OAAQ,SAAU3Y,KAAKya,OAAO8N,YAExC,KAAKvoB,MAAKoO,IAAIyK,YACZ,OAAQ,OAAQ,UAAW7Y,KAAKya,OAAO8N;AAEzC,IAAKvoB,MAAKoO,IAAI2K,aACZ,MAAO/Y,MAAKoE,KAAK,SACfpE,KAAKya,OAAO8N,YAGhB,KAAKvoB,MAAKoO,IAAI4B,OACZ,GAAI3L,GAASrE,KAAKoE,KAAK,QACnB4G,EAAS,IASb,OAR2B,MAAtBhL,KAAKya,OAAOjQ,QACW,MAAtBxK,KAAKya,OAAOjQ,OACdQ,EAAShL,KAAKuoB,YACdvoB,KAAK8lB,OAAO,KAAKrL,QAEjBza,KAAKya,QAGFpW,EAAO2G,EAEhB,KAAKhL,MAAKoO,IAAI2F,QACZ,MAAO/T,MAAKoE,KAAK,SACfpE,KAAKya,OAAO8N,YAIhB,KAAKvoB,MAAKoO,IAAI0R,QACZ,GAAIzb,IAAU,QAAS,KAAM,KAS7B,OARIrE,MAAKya,OAAOmM,GAAG,UAEjBviB,EAAO,GAAKrE,KAAKuoB,YACbvoB,KAAKwK,QAAUxK,KAAKoO,IAAI+S,iBAE1B9c,EAAO,GAAKrE,KAAKya,OAAO8N,cAGrBlkB,CAGT,KAAKrE,MAAKoO,IAAIyR,aACZ,OAAQ,YAAa7f,KAAKya,OAAO8N,YAEnC,KAAKvoB,MAAKoO,IAAI+B,WAEZ,MAAOnQ,MAAKupB,eAAc,GAK9B,GAAIjB,EACJ,IAAItoB,KAAK4mB,GAAG,YAGV,OAFA0B,EAAOtoB,KAAKqoB,eAAc,GAAO,GAAO,GAEjCroB,KAAKwK,OACV,IAAK,IACH,GACInD,GADAhD,EAASrE,KAAKoE,KAAK,SAWvB,OAPIiD,GAFqB,KAArBrH,KAAKya,OAAOjQ,MACVxK,KAAKya,OAAOjQ,QAAUxK,KAAKoO,IAAIqG,MACzBzU,KAAKya,OAAO6Q,gBAEZtrB,KAAKqoB,eAAc,GAAO,GAAO,GAGnCroB,KAAKuoB,YAERlkB,EAAOikB,EAAMjhB,EAAO,IAG7B,KAAKrH,MAAKoO,IAAIoT,aACZ,OAAQ,MAAO8G,GAAO,MAAO,IAAKA,EAAMtoB,KAAKya,OAAO8N,aACtD,KAAKvoB,MAAKoO,IAAIiS,cACZ,OAAQ,MAAOiI,GAAO,MAAO,IAAKA,EAAMtoB,KAAKya,OAAO8N;AACtD,IAAKvoB,MAAKoO,IAAIoU,YACZ,OAAQ,MAAO8F,GAAO,MAAO,IAAKA,EAAMtoB,KAAKya,OAAO8N,aACtD,KAAKvoB,MAAKoO,IAAIqU,YACZ,OAAQ,MAAO6F,GAAO,MAAO,KAAMA,EAAMtoB,KAAKya,OAAO8N,aACvD,KAAKvoB,MAAKoO,IAAIqS,YACZ,OAAQ,MAAO6H,GAAO,MAAO,IAAKA,EAAMtoB,KAAKya,OAAO8N,aACtD,KAAKvoB,MAAKoO,IAAIwU,eAEZ,OAAQ,MAAO0F,GAAO,MAAO,IAAKA,EAAMtoB,KAAKya,OAAO8N,aACtD,KAAKvoB,MAAKoO,IAAI2U,YACZ,OAAQ,MAAOuF,GAAO,MAAO,IAAKA,EAAMtoB,KAAKya,OAAO8N,aACtD,KAAKvoB,MAAKoO,IAAI6U,YACZ,OAAQ,MAAOqF,GAAO,MAAO,IAAKA,EAAMtoB,KAAKya,OAAO8N,aACtD,KAAKvoB,MAAKoO,IAAIgV,WACZ,OAAQ,MAAOkF,GAAO,MAAO,IAAKA,EAAMtoB,KAAKya,OAAO8N,aACtD,KAAKvoB,MAAKoO,IAAImV,YACZ,OAAQ,MAAO+E,GAAO,MAAO,IAAKA,EAAMtoB,KAAKya,OAAO8N,aACtD,KAAKvoB,MAAKoO,IAAI2T,WACZ,OAAQ,MAAOuG,GAAO,MAAO,KAAMA,EAAMtoB,KAAKya,OAAO8N,aACvD,KAAKvoB,MAAKoO,IAAIiU,WACZ,OAAQ,MAAOiG,GAAO,MAAO,KAAMA,EAAMtoB,KAAKya,OAAO8N,aACvD,KAAKvoB,MAAKoO,IAAImT,MAEZ,MADAvhB,MAAKya,QACG,OAAQ,IAAK6N,EACvB,KAAKtoB,MAAKoO,IAAIgS,MAEZ,MADApgB,MAAKya,QACG,OAAQ,IAAK6N,OAEpB,IAAItoB,KAAK4mB,GAAG,UAGjB,IAFA0B,EAAOtoB,KAAKwrB,cAENxrB,KAAKwK,QAAUxK,KAAKuO,KACxB,GAAIvO,KAAKwK,QAAUxK,KAAKoO,IAAIiP,kBAC1BiL,EAAOtoB,KAAK8qB,8BAA8BxC,GAAM,OAC3C,IAAItoB,KAAKwK,QAAUxK,KAAKoO,IAAIoR,cAA+B,MAAfxf,KAAKwK,MACtD8d,EAAOtoB,KAAK+qB,oBAAoBzC,OAC3B;AAAA,GAAmB,MAAftoB,KAAKwK,MAId,MAAO8d,EAFPA,GAAOtoB,KAAKoE,KAAK,QAAQkkB,EAAMtoB,KAAKgrB,mCAMxC1C,GAAOtoB,KAAK+lB,MAAM,QAClB/lB,KAAKya,MAIP,OAAO6N,IASRgD,cAAe,WACd,GAAIjnB,GAASrE,KAAKoE,KAAK,MACvB,IAAIpE,KAAKwK,QAAUxK,KAAKoO,IAAI6F,QAAS,CAEnC,GAAI4U,IAAc,EAAOC,GAAiB,CAU1C,OATI9oB,MAAKya,OAAOjQ,OAASxK,KAAKoO,IAAIkG,YAChCuU,EAAc7oB,KAAKya,OAAOsO,uBAExB/oB,KAAKwK,OAASxK,KAAKoO,IAAImG,eACzBuU,EAAiB9oB,KAAKya,OAAOqM,UAC3B9mB,KAAK+oB,oBACL,MAGG1kB,GACL,EACCwkB,EACAC,EACA9oB,KAAK8lB,OAAO,KAAKrL,OAAOuO,mBAI3B,GAAIxmB,GAAOxC,KAAKyrB,4BACZrqB,IAIJ,OAHmB,MAAfpB,KAAKwK,QACPpJ,EAAOpB,KAAKgrB,+BAEP3mB,EAAO7B,EAAMpB,IASvBqqB,0BAA2B,WAC1B,GAAmB,OAAfzrB,KAAKwK,OAAkBxK,KAAKwK,QAAUxK,KAAKoO,IAAIoP,SAAU,CAC3D,GAAInZ,GAASrE,KAAK+oB,qBAMlB,OAJE1kB,GADErE,KAAKwK,QAAUxK,KAAKoO,IAAIuS,eACjB3gB,KAAK0rB,mBAAmBrnB,IAEvB,KAAMA,GAGb,MAAIrE,MAAK4mB,GAAG,YACV5mB,KAAKqoB,eAAc,GAAM,GAAO,OAEvCroB,MAAK8lB,QAAQ9lB,KAAKoO,IAAIoP,SAAU,cAQnC4N,qBAAsB,WACrB,MAAOprB,MAAK8mB,UACV9mB,KAAK2rB,6BAA8B,MAStCA,6BAA8B,WAC7B,GAAmB,MAAf3rB,KAAKwK,OAAgC,MAAfxK,KAAKwK,MAAe,MAAO;AACrD,GAAInG,GAASrE,KAAK4qB,gBAQlB,OAPI5qB,MAAKwK,QAAUxK,KAAKoO,IAAI+S,iBAC1B9c,GACE,MACAA,EACArE,KAAKya,OAAOmQ,mBAGTvmB,SAILunB,IAAI,SAASrtB,EAAQkB,EAAOJ,GAOlCI,EAAOJ,SAILwsB,aAAc,WACZ,MAAkB,KAAd7rB,KAAKwK,QACPxK,KAAKya,QACE,IAOVqR,YAAa,WACZ,MAAI9rB,MAAKwK,QAAUxK,KAAKoO,IAAIyU,aAC1B7iB,KAAKya,QACE,IAUV8O,cAAe,SAASwC,EAASpD,GAChC,GAAItkB,GAASrE,KAAKoE,KAChBpE,KAAKoqB,0BAA0B2B,EAAU,EAAIpD,EAAO,EAAI,GAE1D,IAAIA,GAAmB,GAAXA,EAAK,GACftkB,EAASA,EAAOskB,GAChB3oB,KAAK8lB,OAAO,KAAKL,uBACZ,CACL,GAAIuG,GAAOhsB,KAAK8lB,OAAO,KAAKmG,iBAAgB,EAE1C5nB,GADEskB,EACOtkB,EAAO2nB,EAAMrD,GAEbtkB,EAAO2nB,GAGpB,MAAO3nB,IAQR+lB,0BAA2B,SAASvhB,GACnC,GAAIqjB,GAAW,UACF,KAATrjB,EACFqjB,EAAW,UACO,IAATrjB,IACTqjB,EAAW,SAEb,IAAI7nB,GAASrE,KAAKoE,KAAK8nB,EACvBlsB,MAAK8lB,OAAO9lB,KAAKoO,IAAI+B,WACrB,IAAIgc,GAAQnsB,KAAKya,OAAOoR,eACpBrpB,GAAO,EAAOiT,KAAU2W,GAAa,CAC5B,KAATvjB,IACFrG,EAAOxC,KAAK8lB,OAAO9lB,KAAKoO,IAAIoP,UAAUxD,OACtCha,KAAKya,QAEPza,KAAK8lB,OAAO,KAAKrL,MACjB,IAAI4R,GAASrsB,KAAKssB,qBASlB,OARAtsB,MAAK8lB,OAAO,KAAKrL,OACJ,IAAT5R,GAAc7I,KAAKwK,QAAUxK,KAAKoO,IAAIsH,QACxCD,EAAMzV,KAAKya,OAAOqL,OAAO,KAAKrL,OAAOqM,UAAU9mB,KAAKusB,iBAAkB,KACtEvsB,KAAK8lB,OAAO,KAAKrL,QAEA,MAAfza,KAAKwK,QACP4hB,EAAapsB,KAAKya,OAAO+R;AAEd,IAAT3jB,EACKxE,EAAOgoB,EAAQF,EAAO1W,EAAK2W,GAE7B/nB,EAAO7B,EAAM6pB,EAAQF,EAAOC,IAOpCG,iBAAkB,WACjB,GAAIloB,KAAU,EAAO,KAWrB,OAVmB,MAAfrE,KAAKwK,QACPnG,EAAO,IAAK,EACZrE,KAAKya,QAEHza,KAAKwK,QAAUxK,KAAKoO,IAAIyP,YAC1BxZ,EAAO,GAAKrE,KAAKga,OACjBha,KAAKya,QAELza,KAAK8lB,QAAQ,IAAK9lB,KAAKoO,IAAIyP,aAEtBxZ,GAQRioB,oBAAqB,WACpB,GAAIjoB,KACJ,IAAkB,KAAdrE,KAAKwK,MACP,KAAMxK,KAAKwK,OAASxK,KAAKuO,KAAK,CAE5B,GADAlK,EAAO9C,KAAKvB,KAAKysB,kBACC,KAAdzsB,KAAKwK,MAEF,CAAA,GAAkB,KAAdxK,KAAKwK,MACd,KAEAxK,MAAK+lB,OAAO,IAAK,KACjB,OALA/lB,KAAKya,OASX,MAAOpW,IAQRooB,eAAgB,WACf,GAAIroB,GAAOpE,KAAKoE,KAAK,SACjByE,EAAO7I,KAAKwsB,YACZL,EAAQnsB,KAAK6rB,eACba,EAAa1sB,KAAK8rB,cAClBtpB,EAAOxC,KAAK8lB,OAAO9lB,KAAKoO,IAAIyP,YAAY7D,OACxClS,EAAQ,IAIZ,OAHyB,KAArB9H,KAAKya,OAAOjQ,QACd1C,EAAQ9H,KAAKya,OAAO8N,aAEfnkB,EAAK5B,EAAMqG,EAAMf,EAAOqkB,EAAOO,IAOvC1B,4BAA6B,WAC5B,GAAI3mB,KAEJ,IADArE,KAAK8lB,OAAO,KAAKrL,OACE,MAAfza,KAAKwK,MACP,KAAMxK,KAAKwK,OAASxK,KAAKuO,MACvBlK,EAAO9C,KAAKvB,KAAK2sB,sBACE,MAAf3sB,KAAKwK,QACPxK,KAAKya,MAKX,OADAza,MAAK8lB,OAAO,KAAKrL,OACVpW,GAORsoB,mBAAoB,WACnB,MAAI3sB,MAAKwK,QAAUxK,KAAKoO,IAAIyU,WACnB7iB,KAAKoE,KAAK,YAAYpE,KAAKya,OAAO8N,aAEpCvoB,KAAKuoB;AAQbiE,UAAW,WACV,OAAOxsB,KAAKwK,OACV,IAAKxK,MAAKoO,IAAIiJ,QAEZ,MADArX,MAAKya,QACG,QACV,KAAKza,MAAKoO,IAAImS,eACd,IAAKvgB,MAAKoO,IAAIoP,SACZ,MAAOxd,MAAK+oB,qBACd,KAAK/oB,MAAKoO,IAAImJ,WAEZ,MADAvX,MAAKya,QACG,WACV,SACE,MAAO,cAKTmS,IAAI,SAASruB,EAAQkB,EAAOJ,GAOlCI,EAAOJ,SAMLwtB,QAAS,WACP,GAAIxoB,GAASrE,KAAKoE,KAAK,MACnB0oB,EAAO9sB,KAAK+sB,eACZf,EAAO,KACPgB,GAAW,CAEf,IAAmB,MAAfhtB,KAAKwK,MAAe,CAGtB,IAFAxK,KAAKya,OACLuR,KACMhsB,KAAKwK,OAASxK,KAAKuO,KAAOvO,KAAKwK,QAAUxK,KAAKoO,IAAIiD,SAAS,CAE/D,GADArR,KAAK2mB,iBACD3mB,KAAKwK,QAAUxK,KAAKoO,IAAI+C,SAAU,CACpC6b,EAAWhtB,KAAKya,OAAOwS,mBACvB,OACK,GAAIjtB,KAAKwK,QAAUxK,KAAKoO,IAAImD,OAAQ,CACzCyb,EAAWhtB,KAAKya,OAAOyS,iBACvB,OAEFlB,EAAKzqB,KAAKvB,KAAKmtB,wBAEjBntB,KAAK2mB,iBAAiBb,OAAO9lB,KAAKoO,IAAIiD,SAASoJ,OAAOyL,2BAEtD8F,GAAOhsB,KAAKotB,iBACZptB,KAAK2mB,iBACD3mB,KAAKwK,QAAUxK,KAAKoO,IAAI+C,SAC1B6b,EAAWhtB,KAAKya,OAAOoS,UACd7sB,KAAKwK,QAAUxK,KAAKoO,IAAImD,SACjCyb,EAAWhtB,KAAKya,OAAO2S,iBAG3B,OAAO/oB,GAAOyoB,EAAMd,EAAMgB,IAK5BD,aAAc,WACZ/sB,KAAK8lB,OAAO,KAAKrL,MACjB,IAAIpW,GAASrE,KAAKuoB,WAElB,OADAvoB,MAAK8lB,OAAO,KAAKrL;AACVpW,GAKT4oB,kBAAmB,WACjB,GAAI5oB,GAASrE,KAAKoE,KAAK,MACnB0oB,EAAO9sB,KAAK+sB,cAChB/sB,MAAK8lB,OAAO,KAAKrL,MAIjB,KAHA,GAAIuR,MACAgB,GAAW,EAEThtB,KAAKwK,OAASxK,KAAKuO,KAAOvO,KAAKwK,QAAUxK,KAAKoO,IAAIiD,SAAS,CAC/D,GAAIrR,KAAKwK,QAAUxK,KAAKoO,IAAI+C,SAAU,CACpC6b,EAAWhtB,KAAKya,OAAOwS,mBACvB,OACK,GAAIjtB,KAAKwK,QAAUxK,KAAKoO,IAAImD,OAAQ,CACzCyb,EAAWhtB,KAAKya,OAAOyS,iBACvB,OAEFlB,EAAKzqB,KAAKvB,KAAKmtB,wBAGjB,MAAO9oB,GAAOyoB,EAAMd,EAAMgB,IAK5BE,gBAAiB,WACfltB,KAAK8lB,OAAO,KAAKrL,MAEjB,KADA,GAAIuR,MACEhsB,KAAKwK,OAASxK,KAAKuO,KAAOvO,KAAKwK,QAAUxK,KAAKoO,IAAIiD,SACtD2a,EAAKzqB,KAAKvB,KAAKmtB,uBAEjB,OAAOnB,UAILqB,IAAI,SAAS9uB,EAAQkB,EAAOJ,GAOlCI,EAAOJ,SAILiuB,gBAAiB,SAAS9iB,GACxB,GAAIwhB,KAEJ,KADAhsB,KAAK8lB,OAAO,KAAKrL,OACXza,KAAKwK,OAASxK,KAAKuO,KAAOvO,KAAKwK,QAAUA,GAC7CwhB,EAAKzqB,KAAKvB,KAAKmtB,uBAGjB,OADAntB,MAAK8lB,OAAOtb,GAAOiQ,OAAOyL,uBACnB8F,GAKRuB,WAAY,WACX,GAAIlpB,GAASrE,KAAKoE,KAAK,QACvBpE,MAAK8lB,OAAO,KAAKrL,MACjB,IAAIqS,GAAO9sB,KAAKuoB,WAChBvoB,MAAK8lB,OAAO,KAAKrL,MACjB,IAAIuR,KAMJ,OAJEA,GADiB,MAAfhsB,KAAKwK,MACAxK,KAAKstB,gBAAgBttB,KAAKoO,IAAIuD,YAE9B3R,KAAKotB,iBAEP/oB,EAAOyoB,EAAMd,IAErBwB,QAAS,WACR,GAAInpB,GAASrE,KAAKoE,KAAK,MACnB4nB,EAAOhsB,KAAKotB;AAChBptB,KAAK8lB,OAAO9lB,KAAKoO,IAAIqD,SAASgJ,OAAOqL,OAAO,KAAKrL,MACjD,IAAIqS,GAAO9sB,KAAKuoB,WAEhB,OADAvoB,MAAK8lB,OAAO,KAAKrL,OAAOqL,OAAO,KAAKrL,OAC7BpW,EAAOyoB,EAAMd,IAErByB,SAAU,WACT,GAAIppB,GAASrE,KAAKoE,KAAK,MACvBpE,MAAK8lB,OAAO,KAAKrL,MACjB,IAAIiT,GAAQ,KAAMC,EAAQ,KAAMC,EAAQ,IACrB,OAAf5tB,KAAKwK,OACPkjB,EAAQ1tB,KAAK8mB,UAAU9mB,KAAKuoB,UAAW,KACvCvoB,KAAK8lB,OAAO,KAAKrL,QAEjBza,KAAKya,OAEY,MAAfza,KAAKwK,OACPmjB,EAAQ3tB,KAAK8mB,UAAU9mB,KAAKuoB,UAAW,KACvCvoB,KAAK8lB,OAAO,KAAKrL,QAEjBza,KAAKya,OAEY,MAAfza,KAAKwK,OACPojB,EAAQ5tB,KAAK8mB,UAAU9mB,KAAKuoB,UAAW,KACvCvoB,KAAK8lB,OAAO,KAAKrL,QAEjBza,KAAKya,MAEP,IAAIuR,GAAO,IAMX,OAJEA,GADiB,MAAfhsB,KAAKwK,MACAxK,KAAKstB,gBAAgBttB,KAAKoO,IAAI6D,UAE9BjS,KAAKotB,iBAEP/oB,EAAOqpB,EAAOC,EAAOC,EAAO5B,IAOpC6B,aAAc,WACb,GAAIxpB,GAASrE,KAAKoE,KAAK,UACvBpE,MAAK8lB,OAAO,KAAKrL,MACjB,IAAI6N,GAAOtoB,KAAKuoB,WAChBvoB,MAAK8lB,OAAO9lB,KAAKoO,IAAIyE,MAAM4H,MAC3B,IAAIsM,GAAO/mB,KAAK8tB,wBACd1jB,GAAM,CACJpK,MAAKwK,QAAUxK,KAAKoO,IAAI+S,iBAC1B/W,EAAM2c,EACNA,EAAO/mB,KAAKya,OAAOqT,yBAErB9tB,KAAK8lB,OAAO,KAAKrL,MACjB,IAAIuR,KAMJ,OAJEA,GADiB,MAAfhsB,KAAKwK,MACAxK,KAAKstB,gBAAgBttB,KAAKoO,IAAIiE,cAE9BrS,KAAKotB,iBAEP/oB,EAAOikB,EAAMle,EAAK2c,EAAMiF,IAOhC8B,sBAAuB;AACpB,GAAmB,MAAf9tB,KAAKwK,MACP,MAAOxK,MAAKya,OAAO4N,eAAc,GAAO,GAAO,EAC1C,IAAIroB,KAAKwK,QAAUxK,KAAKoO,IAAIgJ,OAAQ,CACzC,GAAI/S,GAASrE,KAAKoE,KAAK,OACvBpE,MAAKya,OAAOqL,OAAO,KAAKrL,MACxB,IAAI0Q,GAAanrB,KAAKorB,sBAEtB,OADAprB,MAAK8lB,OAAO,KAAKrL,OACVpW,EAAO8mB,GAAY,GAE1B,MAAOnrB,MAAKqoB,eAAc,GAAO,GAAO,UAK1C0F,IAAI,SAASxvB,EAAQkB,EAAOJ,GAOlCI,EAAOJ,SAMLqmB,WAAY,WACV,MAAI1lB,MAAKwK,OAASxK,KAAKoO,IAAIoH,YAClBxV,KAAKguB,iBAELhuB,KAAKiuB,4BAKZC,IAAI,SAAS3vB,EAAQkB,EAAOJ,GAOlCI,EAAOJ,SASL2uB,eAAgB,WACdhuB,KAAK8lB,OAAO9lB,KAAKoO,IAAIoH,aAAaiF,MAClC,IAAIpW,GAASrE,KAAKoE,KAAK,YACvB,IAAkB,KAAdpE,KAAKwK,MAEP,MADAxK,MAAKqlB,kBAAoB,IAClBhhB,GAAQ,IAAKrE,KAAKisB,iBAAgB,GAEtCjsB,MAAKwK,QAAUxK,KAAKoO,IAAIoH,cACzBxV,KAAK+lB,OAAO,IAAK/lB,KAAKoO,IAAIoP,WAC1Bxd,KAAKya,OAEP,IAAIjY,GAAOxC,KAAK+oB,qBAChB,IAAkB,KAAd/oB,KAAKwK,MAAc,CACrBxK,KAAKqlB,iBAAmB7iB,CACxB,IAAIwpB,GAAOhsB,KAAKylB,mBAAmB0I,qBAEnC,OADAnuB,MAAK8lB,OAAO9lB,KAAKuO,KACVlK,EAAO7B,EAAMwpB,GACf,GAAkB,KAAdhsB,KAAKwK,MAEd,MADAxK,MAAKqlB,iBAAmB7iB,EACjB6B,EAAO7B,EAAMxC,KAAKisB,iBAAgB,GACpC,IAAmB,MAAfjsB,KAAKwK,MAEd,MAAOxK,MAAKoE,KAAK,SACd,KAAM5B,EAAKsB,MAAM,IAChB9D,KAAKgrB;AAGThrB,KAAK+lB,OAAO,IAAK,MAEjB/lB,KAAKqlB,iBAAmB7iB,CACxB,IAAIwpB,GAAOhsB,KAAKmuB,qBAEhB,OADAnuB,MAAK8lB,OAAO9lB,KAAKuO,KACVlK,EAAO7B,EAAMwpB,IAUzBjD,oBAAqB,WAIpB,MAHI/oB,MAAKwK,QAAUxK,KAAKoO,IAAIoH,aAC1BxV,KAAKya,OAAOqL,OAAO9lB,KAAKoO,IAAImS,gBAAgB9F,OAEvCza,KAAK8mB,UAAU9mB,KAAKoO,IAAIoP,SAAUxd,KAAKoO,IAAImS,gBAAgB,IASnE6N,oBAAqB,WAElB,IADA,GAAI/pB,MACErE,KAAKwK,QAAUxK,KAAKuO,MACtBvO,KAAK8lB,OAAO9lB,KAAKoO,IAAIsH,OAAO+E,OAC5Bza,KAAK8mB,UAAU9mB,KAAKquB,yBAA0B,KAAK7pB,QAAQ,SAASuiB,GAC9D1lB,MAAMiK,QAAQyb,GAChB1iB,EAASA,EAAO5D,OAAOsmB,GAEvB1iB,EAAO9C,KAAKwlB,KAGb/mB,KAAKwK,QAAUxK,KAAKoO,IAAIsH,SAE/B,MAAOrR,IAQViqB,4BAA6B,SAASrP,GAErC,IADA,GAAI5a,MACErE,KAAKwK,QAAUxK,KAAKuO,KAAK,CAC7B,GAAInK,GAAOpE,KAAKoE,KAAK,OACjBmqB,EAAKvuB,KAAKwuB,mBAAmBvP,EAAO,MAAO,EAW/C,IAVGjf,KAAKwK,QAAUxK,KAAKoO,IAAIyE,OACzB7S,KAAKya,OAAOqL,OAAO9lB,KAAKoO,IAAIoP,UAC5B+Q,EAAG,GAAKvuB,KAAKga,OACbha,KAAKya,QAEP8T,EAAG,GAAKtP,EAAO,GAAGxe,OAAO8tB,EAAG,IACxBtP,EAAO,MAAO,IAChBsP,EAAG,GAAKtP,EAAO,IAEjB5a,EAAO9C,KAAK6C,EAAK3C,MAAMzB,KAAMuuB,IACX,MAAfvuB,KAAKwK,MACN,KAEAxK,MAAKya,OAGT,MAAOpW,IASRgqB,yBAA0B,WACzB,GAAIhqB,GAASrE,KAAKoE,KAAK,OACnBqR,EAAMzV,KAAKwuB,oBACf,IAAGxuB,KAAKwK,QAAUxK,KAAKoO,IAAIyE,KACzB7S,KAAKya,OAAOqL,OAAO9lB,KAAKoO,IAAIoP;AAC5B/H,EAAI,GAAKzV,KAAKga,OACdha,KAAKya,WACA,IAAmB,MAAfza,KAAKwK,MAGd,MAFAiL,GAAMzV,KAAKya,OAAO6T,4BAA4B7Y,GAC9CzV,KAAK8lB,OAAO,KAAKrL,OACVhF,CAET,OAAOpR,GAAO5C,MAAMzB,KAAMyV,IAS3B+Y,mBAAoB,SAASC,GAC1B,GAAI5lB,IAAO,CAER4lB,IAAezuB,KAAKwK,QAAUxK,KAAKoO,IAAI+B,YAAcnQ,KAAKwK,QAAUxK,KAAKoO,IAAIiC,UAE9ExH,EAAO7I,KAAKwK,QAAUxK,KAAKoO,IAAI+B,WAAa,WAAa,WACzDnQ,KAAKya,OAEP,IAAIjY,GAAOxC,KAAK+oB,qBAChB,QAAQvmB,EAAMA,EAAKA,EAAKjD,OAAS,GAAIsJ,UAIrC6lB,IAAI,SAASnwB,EAAQkB,EAAOJ,GAOlC,GAAIsvB,IACFC,MAAO,KACPC,MAAO,KACPC,MAAO,KACPC,MAAOthB,OAAOuhB,aAAa,IAC3BC,MAAOxhB,OAAOuhB,aAAa,IAC3BE,MAAOzhB,OAAOuhB,aAAa,IAC3BG,OAAQ,KACRC,MAAO,IACPC,MAAO,IACPC,MAAQ,IAGV7vB,GAAOJ,SAILkwB,sBAAuB,SAASvV,GAC9B,MAAOA,GAAKwV,QACV,oBACA,SAASC,GACP,MAAOd,GAAYc,MAczBjE,YAAa,WACX,GAAIxrB,KAAK4mB,GAAG,iBACV,MAAO5mB,MAAK0vB,oBAEZ,QAAO1vB,KAAKwK,OAGV,IAAKxK,MAAKoO,IAAI+P,2BACZ,GAAIrW,GAAQ9H,KAAKoE,KAAK,UAClB4V,EAAOha,KAAKga,OACZtM,GAAgB,EAChBiiB,EAAyB,MAAb7nB,EAAM,IAA2B,MAAbA,EAAM,EAa1C,OAZI6nB,IACFjiB,EAA4B,MAAZsM,EAAK,GACrBA,EAAOA,EAAK/V,UAAU,EAAG+V,EAAKza,OAAS,KAEvCmO,EAA4B,MAAZsM,EAAK,GACrBA,EAAOA,EAAK/V,UAAU,EAAG+V,EAAKza,OAAS,IAEzCuI,EAAQA,EAAM4F,EAAe1N,KAAKuvB,sBAAsBvV;AACpD2V,IACF7nB,GAAS,OAAQ,SAAUA,IAE7B9H,KAAKya,OACDza,KAAKwK,QAAUxK,KAAKoO,IAAIuS,eAEnB3gB,KAAK0rB,mBAAmB5jB,GAGxBA,CAEX,KAAK9H,MAAKoO,IAAI4Q,gBACZ,MAAOhf,MAAKya,OAAOwQ,qBACjBjrB,KAAKoO,IAAIgR,cAEb,KAAK,IACH,MAAOpf,MAAKya,OAAOwQ,qBAAqB,IAC1C,KAAK,KACL,IAAK,KACH,OAAQ,OAAQ,SAAUjrB,KAAKya,OAAOwQ,qBAAqB,KAG7D,KAAK,IACL,IAAKjrB,MAAKoO,IAAI6O,UACd,IAAKjd,MAAKoO,IAAI4O,UACZ,GAAI3Y,GAASrE,KAAKoE,KAAK,UACnB0D,EAAQ9H,KAAKga,MASjB,OARmB,MAAfha,KAAKwK,QACPxK,KAAKya,OAAOqL,QACV9lB,KAAKoO,IAAI6O,UAAWjd,KAAKoO,IAAI4O,YAE/BlV,GAAS9H,KAAKga,QAEhB3V,EAASA,EAAOyD,GAChB9H,KAAKya,OACEpW,CAGT,KAAKrE,MAAKoO,IAAIoH,YACd,IAAKxV,MAAKoO,IAAImS,eACd,IAAKvgB,MAAKoO,IAAIoP,SACZ,GAAI1V,GAAQ9H,KAAK+oB,sBACb1kB,GAAU,WAAYyD,EAQ1B,KAPK9H,KAAKwK,OAASxK,KAAKoO,IAAIuS,iBAE1B3gB,KAAKya,OAAOqL,QAAQ9lB,KAAKoO,IAAIoP,SAAUxd,KAAKoO,IAAI6F,UAChD5P,EAAO,IAAMyD,EAAO9H,KAAKga,QACzBha,KAAKya,QAGc,MAAfza,KAAKwK,OACTnG,GAAU,SAAUA,EAAQrE,KAAKya,OAAO8N,aACxCvoB,KAAK8lB,OAAO,KAAKrL,MAEnB,OAAOpW,EAGT,KAAKrE,MAAKoO,IAAIiJ,QACd,IAAK,IACH,MAAOrX,MAAKmoB,YACd,SACE,GAAIyH,GAAM5vB,KAAK+lB,MAAM,SAGrB,OADA/lB,MAAKya,OACEmV,IAOd7E,oBAAqB,SAASzC;AAC7B,GAAIjkB,EAOJ,OANmB,MAAfrE,KAAKwK,OACPnG,GAAU,SAAUikB,EAAMtoB,KAAKya,OAAO8N,aACtCvoB,KAAK8lB,OAAO,KAAKrL,QACRza,KAAKwK,QAAUxK,KAAKoO,IAAIkR,6BACjCjb,GAAU,SAAUikB,EAAMtoB,KAAK6vB,8BAE1BxrB,GAYRwrB,0BAA2B,WAC1B,GAAIxrB,GAAS,IA+Bb,OA9BIrE,MAAKwK,QAAUxK,KAAKoO,IAAI0P,2BAC1BzZ,EAASrE,KAAKoE,KAAK,WAAU,EAAOpE,KAAKga,QACzCha,KAAKya,QACIza,KAAKwK,QAAUxK,KAAKoO,IAAIkR,4BAC7Btf,KAAKya,OAAOjQ,QAAUxK,KAAKoO,IAAIsP,kBACjCrZ,GAAU,MAAOrE,KAAKga,QACI,MAAtBha,KAAKya,OAAOjQ,QACdnG,GAAU,SAAUA,EAAQrE,KAAKya,OAAO8N,aACxCvoB,KAAK8lB,OAAO,KAAKrL,SAGnBpW,EAASrE,KAAKuoB,YAEhBvoB,KAAK8lB,OAAO,KAAKrL,QACRza,KAAKwK,QAAUxK,KAAKoO,IAAIoR,cACjCnb,EAASrE,KAAKya,OAAO4N,eAAc,GAAO,GAAO,GACjDroB,KAAK8lB,OAAO,KAAKrL,QACO,MAAfza,KAAKwK,OACdnG,GAAU,SAAUA,EAAQrE,KAAKya,OAAO8N,aACxCvoB,KAAK8lB,OAAO,KAAKrL,QACRza,KAAKwK,QAAUxK,KAAKoO,IAAIyP,WACjCxZ,EAASrE,KAAKqoB,eAAc,GAAO,GAAM,GAEzCroB,KAAK8lB,QACH9lB,KAAKoO,IAAIyP,WACT7d,KAAKoO,IAAIoR,aACTxf,KAAKoO,IAAIkR,2BACTtf,KAAKoO,IAAI0P,4BAGNzZ,GAKR4mB,qBAAsB,SAASnF,GAC9B,GAAI9lB,KAAKwK,QAAUsb,EAEjB,MADA9lB,MAAKya;AACE,IAET,IAAIqV,GAAQ9vB,KAAK6vB,2BACjB,IAAI7vB,KAAKwK,QAAUsb,EAEjB,MADA9lB,MAAKya,OACEqV,CAOT,KALA,GAAIzrB,IACF,MAAO,IACLyrB,EACA9vB,KAAK6vB,6BAEH7vB,KAAKwK,QAAUsb,GACnBzhB,EAAO,IACL,MAAO,IAAKA,EAAO,GAAIrE,KAAK6vB,4BAIhC,OADA7vB,MAAK8lB,OAAOA,GAAQrL,OACbpW,GAKRqrB,mBAAoB,WACnB,GAAIrrB,GAASrE,KAAKoE,KAAK,SACnB5B,EAAOxC,KAAKga,MAEhB,OADAha,MAAKya,OACEpW,EAAO7B,UAIZutB,IAAI,SAASxxB,EAAQkB,EAAOJ,GAMlCI,EAAOJ,SAOL8uB,oBAAqB,WAEnB,IADA,GAAI9pB,MACErE,KAAKwK,QAAUxK,KAAKuO,KAAsB,MAAfvO,KAAKwK,OAAe,CACnD,GAAIwlB,GAAYhwB,KAAKiuB,oBACjB+B,KACE3uB,MAAMiK,QAAQ0kB,GAChB3rB,EAASA,EAAO5D,OAAOuvB,GAEvB3rB,EAAO9C,KAAKyuB,IAIlB,MAAO3rB,IAYR4pB,mBAAoB,WACnB,OAAOjuB,KAAKwK,OACV,IAAKxK,MAAKoO,IAAI+B,WACZ,MAAOnQ,MAAKupB,eAEd,KAAKvpB,MAAKoO,IAAIoI,WACd,IAAKxW,MAAKoO,IAAIsI,QACZ,GAAIiS,GAAO3oB,KAAKipB,kBAChB,QAAOjpB,KAAKwK,OACV,IAAKxK,MAAKoO,IAAI6F,QACZ,MAAOjU,MAAK0oB,WAAWC,EACzB,KAAK3oB,MAAKoO,IAAI+F,YACZ,MAAOnU,MAAKiqB,eAAetB,EAC7B,SACE,GAAIiH,GAAM5vB,KAAK+lB,OAAO/lB,KAAKoO,IAAI6F,QAASjU,KAAKoO,IAAI+F,aAEjD,OADAnU,MAAKya,OACEmV,EAEb,IAAK5vB,MAAKoO,IAAI6F,QACZ,MAAOjU,MAAK0oB,WAAW,EACzB,KAAK1oB,MAAKoO,IAAI+F,YACZ,MAAOnU,MAAKiqB,eAAe;AAC7B,IAAKjqB,MAAKoO,IAAIiG,QACZ,MAAOrU,MAAKsqB,YACd,KAAKtqB,MAAKoO,IAAIsH,MACZ,GAAI4S,GAAOtoB,KAAKouB,qBAEhB,OADApuB,MAAK8lB,OAAO,KAAKL,mBACV6C,CACT,KAAKtoB,MAAKoO,IAAIiC,QACZ,MAAOrQ,MAAKya,OAAOwV,iBACrB,KAAKjwB,MAAKoO,IAAIoH,YACZ,MAAOxV,MAAKguB,gBACd,KAAKhuB,MAAKoO,IAAIgI,gBACZ,GAAI/R,GAASrE,KAAKoE,KAAK,OAGvB,OAFApE,MAAKya,OAAOqL,OAAO,KAAKrL,OAAOqL,OAAO,KAAKrL,OAAOqL,OAAO,KACzD9lB,KAAKuD,MAAMiW,MAAO,EACXnV,EAAOrE,KAAKuD,MAAMS,OAAOC,UAC9BjE,KAAKuD,MAAMW,QAEf,SACE,MAAOlE,MAAKotB,mBASjB8C,sBAAuB,WAEtB,IADA,GAAI7rB,MACErE,KAAKwK,OAASxK,KAAKuO,KAAsB,MAAfvO,KAAKwK,OAAe,CAClD,GAAIwlB,GAAYhwB,KAAKmtB,sBACjB6C,KACE3uB,MAAMiK,QAAQ0kB,GAChB3rB,EAASA,EAAO5D,OAAOuvB,GAEvB3rB,EAAO9C,KAAKyuB,IAIlB,MAAO3rB,IAQR4rB,gBAAiB,WAChB,GAAI5rB,GAASrE,KAAK8mB,UAAU,WAC1B9mB,KAAK8lB,OAAO9lB,KAAKoO,IAAIoP,SACrB,IAAInZ,GAASrE,KAAKoE,KAAK,YACnB5B,EAAOxC,KAAKga,MAEhB,OADAha,MAAKya,OAAOqL,OAAO,KAAKrL,OACjBpW,EAAO7B,EAAMxC,KAAKuoB,cACxB,KAAK,EAER,OADAvoB,MAAKkmB,uBACE7hB,GAQR8rB,kBAAmB,WAClB,MAAOnwB,MAAK8mB,UAAU,WACpB9mB,KAAK8lB,OAAO9lB,KAAKoO,IAAIoP,SACrB,IAAIhb,GAAOxC,KAAKga,MAEhB,OADAha,MAAKya,OAAOqL,OAAO,KAAKrL;CAChBjY,EAAMxC,KAAKuoB,cAClB,MAQJ4E,qBAAsB,WACrB,OAAOntB,KAAKwK,OACV,IAAKxK,MAAKoO,IAAI+B,WACZ,MAAOnQ,MAAKupB,eAEd,KAAKvpB,MAAKoO,IAAIoI,WACd,IAAKxW,MAAKoO,IAAIsI,QACZ,GAAIiS,GAAO3oB,KAAKipB,kBAChB,QAAOjpB,KAAKwK,OACV,IAAKxK,MAAKoO,IAAI6F,QACZ,MAAOjU,MAAK0oB,WAAWC,EACzB,KAAK3oB,MAAKoO,IAAI+F,YACZ,MAAOnU,MAAKiqB,eAAetB,EAC7B,SACE,GAAIiH,GAAM5vB,KAAK+lB,OAAO/lB,KAAKoO,IAAI6F,QAASjU,KAAKoO,IAAI+F,aAGjD,OADAnU,MAAKya,OACEmV,EAEb,IAAK5vB,MAAKoO,IAAI6F,QACZ,MAAOjU,MAAK0oB,WAAW,EACzB,KAAK1oB,MAAKoO,IAAI+F,YACZ,MAAOnU,MAAKiqB,eAAe,EAC7B,KAAKjqB,MAAKoO,IAAIiG,QACZ,MAAOrU,MAAKsqB,YACd,KAAKtqB,MAAKoO,IAAIgI,gBACZpW,KAAKya,OAAOqL,OAAO,KAAKrL,OAAOqL,OAAO,KAAKrL,OAAOqL,OAAO,KAAKrL,OAC9Dza,KAAK4lB,WAAW,8DAClB,SACE,MAAO5lB,MAAKotB,mBAMjBA,eAAgB,WAEf,OAAOptB,KAAKwK,OAEV,IAAK,IAAK,MAAOxK,MAAKisB,iBAAgB,EAEtC,KAAKjsB,MAAKoO,IAAI6C,KAAM,MAAOjR,MAAKya,OAAOoS,SAEvC,KAAK7sB,MAAKoO,IAAI2E,SAAU,MAAO/S,MAAKowB,aAEpC,KAAKpwB,MAAKoO,IAAI2D,MAAO,MAAO/R,MAAKya,OAAOgT,UAExC,KAAKztB,MAAKoO,IAAI+D;AAAW,MAAOnS,MAAKya,OAAOoT,cAE5C,KAAK7tB,MAAKoO,IAAIqD,QAAS,MAAOzR,MAAKya,OAAO8S,YAE1C,KAAKvtB,MAAKoO,IAAIyD,KAAM,MAAO7R,MAAKya,OAAO+S,SAEvC,KAAKxtB,MAAKoO,IAAIuM,UAAW,MAAO3a,MAAK4pB,cAErC,KAAK5pB,MAAKoO,IAAIwM,cAAe,MAAO5a,MAAK2pB,kBAEzC,KAAK3pB,MAAKoO,IAAImC,SACd,IAAKvQ,MAAKoO,IAAImF,QACd,IAAKvT,MAAKoO,IAAIqF,WACZ,GAAI4c,EACJ,QAAOrwB,KAAKwK,OACV,IAAKxK,MAAKoO,IAAImC,SAAc8f,EAAO,QAAa,MAChD,KAAKrwB,MAAKoO,IAAImF,QAAc8c,EAAO,OAAa,MAChD,KAAKrwB,MAAKoO,IAAIqF,WAAc4c,EAAO,WAErC,GAAI/H,GAAO,IAKX,OAJKtoB,MAAKya,OAAOmM,GAAG,SAClB0B,EAAOtoB,KAAKuoB,aAEdvoB,KAAKkmB,wBACGmK,EAAM/H,EAEhB,KAAKtoB,MAAKoO,IAAI0H,SACZ,GAAI/O,GAAQ/G,KAAKya,OAAOqM,UAAU9mB,KAAKswB,qBAAsB,IAE7D,OADAtwB,MAAKkmB,wBACG,SAAUnf,EAEpB,KAAK/G,MAAKoO,IAAIkI,SACZ,GAAIia,IAAWvwB,KAAKwK,MAAOxK,KAAKuD,MAAM6W,YAClC/V,EAASrE,KAAKoE,KAAK,SACvB,IAAIpE,KAAKya,OAAOjQ,QAAUxK,KAAKoO,IAAIuS,eAAgB,CAEjD3gB,KAAKuD,MAAM8K,OAAO9M,KAAKgvB,EACvB,IAAIjI,GAAOtoB,KAAKya,OAAO8N,WAEvB,OADAvoB,MAAK8lB,OAAO,KAAKL,mBACV6C,EAET,GAAIvhB,GAAQ/G,KAAK8mB,UAAU,WACzB,GAAItkB,GAAOxC,KAAK8lB,OAAO9lB,KAAKoO,IAAIyP,YAAY7D,OACxClS,EAAQ,IAIZ,OAH0B,MAAtB9H,KAAKya,OAAOjQ,QACd1C,EAAQ9H,KAAKya,OAAO8N;CAEd/lB,EAAMsF,IACb,IAEH,OADA9H,MAAKkmB,uBACE7hB,EAAO,UAAW0C,EAE3B,KAAK/G,MAAKoO,IAAIyF,OACZ,GAAIxP,GAASrE,KAAKoE,KAAK,QACnBosB,EAAyC,MAAtBxwB,KAAKya,OAAOjQ,KACnCgmB,IAAmBxwB,KAAKya,MACxB,IAAIrZ,GAAOpB,KAAK8mB,UAAU9mB,KAAKuoB,UAAW,IAK1C,OAJIiI,IACFxwB,KAAK8lB,OAAO,KAAKrL,OAEnBza,KAAKkmB,uBACE7hB,EAAOjD,EAEhB,KAAKpB,MAAKoO,IAAIgO,cACZ,GAAI/X,GAASrE,KAAKoE,KAAK,UAAUpE,KAAKga,OAEtC,OADAha,MAAKya,OACEpW,CAET,KAAKrE,MAAKoO,IAAI8I,QACZ,GAAI7S,GAASrE,KAAKoE,KAAK,QACvBpE,MAAKya,OAAOqL,OAAO,KAAKrL,MACxB,IAAI1T,GAAQ/G,KAAK8mB,UAAU9mB,KAAKqoB,cAAe,IAO/C,OANIroB,MAAK8lB,OAAO,KAAKrL,OAAOqL,OAAO,MACjCzhB,EAASA,EAAO0C,GAChB/G,KAAKylB,oBAELphB,EAASA,EAAO0C,GAEV1C,CAEV,KAAKrE,MAAKoO,IAAImE,UACZ,GAAmCke,GAASzE,EAAxC3nB,EAASrE,KAAKoE,KAAK,UAIvB,IAHApE,KAAKya,OAAOqL,OAAO,KAAKrL,OACxBgW,EAAUzwB,KAAKmwB,oBACfnwB,KAAK8lB,OAAO,KAAKL,mBACE,MAAfzlB,KAAKwK,MAAe,CAGtB,IAFAwhB,KACAhsB,KAAKya,OACCza,KAAKwK,OAASxK,KAAKuO,KAAOvO,KAAKwK,QAAUxK,KAAKoO,IAAIqE,cACtDuZ,EAAKzqB,KAAKvB,KAAKotB,iBAEjBptB,MAAK2mB,iBAAiBb,OAAO9lB,KAAKoO,IAAIqE,cAAcgI,OAAOyL,2BAE3D8F,GAAOhsB,KAAKotB,gBAEd,OAAO/oB,GAAOosB,EAASzE,EAGzB,KAAKhsB,MAAKoO,IAAIqC,MACZ,MAAOzQ,MAAK0wB,UAEd,KAAK1wB,MAAKoO,IAAI2C,QACZ,GAAI1M,GAASrE,KAAKoE,KAAK,SACnBkkB,EAAOtoB,KAAKya,OAAO8N;AAEvB,MADAvoB,MAAKkmB,uBACE7hB,EAAOikB,EAEhB,KAAK,IACL,IAAKtoB,MAAKoO,IAAIkQ,YAEZ,MADAte,MAAKya,OACE,IAET,KAAKza,MAAKoO,IAAIoP,SACZ,GAAI+S,IAAWvwB,KAAKwK,MAAOxK,KAAKuD,MAAM6W,YAClCuW,EAAQ3wB,KAAKga,MACjB,IAA0B,MAAtBha,KAAKya,OAAOjQ,MAAe,CAC7B,GAAInG,GAASrE,KAAKoE,KAAK,QAEvB,OADApE,MAAKya,OACEpW,EAAOssB,GAGd3wB,KAAKuD,MAAM8K,OAAO9M,KAAKgvB,EACvB,IAAIjI,GAAOtoB,KAAKya,OAAO8N,WAEvB,OADAvoB,MAAK8lB,QAAQ,IAAK9lB,KAAKoO,IAAIkQ,cAAcmH,mBAClC6C,CAGX,KAAKtoB,MAAKoO,IAAIuF,OACZ,GAAItP,GAASrE,KAAKoE,KAAK,QACnBusB,EAAQ3wB,KAAKya,OAAOqL,OAAO9lB,KAAKoO,IAAIoP,UAAUxD,MAElD,OADAha,MAAKya,OAAOyL,uBACL7hB,EAAOssB,EAEhB,SACE,GAAIrI,GAAOtoB,KAAKuoB,WAEhB,OADAvoB,MAAKkmB,uBACEoC,IAQZ2D,gBAAiB,SAAS2E,GACzB5wB,KAAK8lB,OAAO,KAAKL,kBACjB,IAAIuG,GAAO4E,EACT5wB,KAAKmuB,sBACHnuB,KAAKkwB,uBAGT,OADAlwB,MAAK8lB,OAAO,KAAKL,mBACVuG,SAIL6E,IAAI,SAAStyB,EAAQkB,EAAOJ,GAMlCI,EAAOJ,SAOL+wB,YAAa,WACXpwB,KAAK8lB,OAAO9lB,KAAKoO,IAAI2E,UAAU0H,MAC/B,IAAIpW,GAASrE,KAAKoE,KAAK,SACvBpE,MAAK8lB,OAAO,KAAKrL,MACjB,IAAI6N,GAAOtoB,KAAKuoB,WAChBvoB,MAAK8lB,OAAO,KAAKrL,MACjB,IAAIqW,GAAQ9wB,KAAK+wB,uBACjB,OAAO1sB,GAAOikB,EAAMwI,IAOrBC,sBAAuB;AAEtB,GAAIjL,GAAS,KAAMzhB,IAmBnB,KAlBmB,MAAfrE,KAAKwK,MACPsb,EAAS,IACe,MAAf9lB,KAAKwK,MACdsb,EAAS9lB,KAAKoO,IAAI6E,YAElBjT,KAAK8lB,QAAQ,IAAK,MAGpB9lB,KAAKya,OACc,MAAfza,KAAKwK,OAEPxK,KAAKya,OAGHza,KAAKwK,QAAUxK,KAAKoO,IAAIkQ,aAC1Bte,KAAKya,OAGDza,KAAKwK,QAAUxK,KAAKuO,KAAOvO,KAAKwK,QAAUsb,GAC9CzhB,EAAO9C,KAAMvB,KAAKgxB,eAAelL,GAOnC,OAJA9lB,MAAK8lB,OAAOA,GAAQrL,OAChBqL,IAAW9lB,KAAKoO,IAAI6E,aACtBjT,KAAKkmB,uBAEA7hB,GAOR2sB,eAAgB,SAASC,GACxB,GAAI5sB,IACF0W,WAAW,EACXiR,QAWF,KATIhsB,KAAKwK,QAAUxK,KAAKoO,IAAI+E,OAC1B9O,EAAO0W,UAAY/a,KAAKya,OAAO8N,YACtBvoB,KAAKwK,QAAUxK,KAAKoO,IAAIiF,UAEjCrT,KAAKya,OAELza,KAAK8lB,QAAQ9lB,KAAKoO,IAAI+E,OAAQnT,KAAKoO,IAAIiF,YAEzCrT,KAAK8lB,QAAQ,IAAK,MAAMrL,OAEtBza,KAAKwK,OAASxK,KAAKuO,KAChBvO,KAAKwK,QAAUymB,GACfjxB,KAAKwK,QAAUxK,KAAKoO,IAAI+E,QACxBnT,KAAKwK,QAAUxK,KAAKoO,IAAIiF,WAE3BhP,EAAO2nB,KAAKzqB,KAAKvB,KAAKmtB,uBAExB,OAAO9oB,UAIL6sB,IAAI,SAAS3yB,EAAQkB,EAAOJ,GAMlCI,EAAOJ,SAULqxB,SAAU,WAGR1wB,KAAK8lB,OAAO9lB,KAAKoO,IAAIqC,MACrB,IAAIpM,GAASrE,KAAKoE,KAAK,OACnBjF,EAAOa,KAAKylB,mBAAmB2H,iBAC/B+D,GAAU,EACVC,IAGJ,KADApxB,KAAK2mB,iBACC3mB,KAAKwK,QAAUxK,KAAKoO,IAAIuC,SAAS,CACrC3Q,KAAKya,OAAOqL,OAAO,KAAKrL,MACxB,IAAI4W,GAASrxB,KAAK+oB,sBACduI,EAAUtxB,KAAKqoB,eAAc,GAAM,GAAO;AAC9CroB,KAAK8lB,OAAO,KAAKL,mBACjB2L,EAAQ7vB,MACNgwB,UAAWF,EACXze,GAAI0e,EACJtF,KAAMhsB,KAAKotB,mBAEbptB,KAAK2mB,iBAKP,MAHI3mB,MAAKwK,QAAUxK,KAAKoO,IAAIyC,YAC1BsgB,EAAUnxB,KAAKylB,mBAAmB2H,kBAE7B/oB,EAAOlF,EAAMiyB,EAASD,UAI3BK,IAAI,SAASjzB,EAAQkB,EAAOJ,GAMlCI,EAAOJ,SAgBLgpB,cAAe,SAASoJ,EAAWC,EAAUzjB,GAC3C,GAAI5J,EAGJ,IAAIrE,KAAK4mB,IAAI5mB,KAAKoO,IAAIyP,WAAY,MAChCxZ,EAASrE,KAAK2xB,wBAAwBD,EAAUzjB,OAC3C,IAAIjO,KAAK4mB,IAAI5mB,KAAKoO,IAAImS,eAAgBvgB,KAAKoO,IAAIoP,WAAY,CAChEnZ,EAASrE,KAAKoE,MACd,IAAI5B,GAAOxC,KAAK+oB,qBAChB,IACE/oB,KAAKwK,OAASxK,KAAKoO,IAAIuS,gBACN,KAAd3gB,KAAKwK,MAGR,GAAmB,GAAfhI,EAAKjD,OAAa,CACpB,GAAIqyB,GAAUpvB,EAAK,GAAGmC,aAEpBN,GADc,SAAZutB,EACOvtB,EAAO,WAAW,GACN,UAAZutB,EACAvtB,EAAO,WAAW,IAGjB,WAAY7B,EAAK,QAI7B6B,IAAU,WAAY7B,OAGxB6B,IAAU,KAAMA,OAETrE,MAAKwK,QAAUxK,KAAKoO,IAAIkI,UACjCtW,KAAKya,OACLpW,GAAU,MAAO,YAEjBrE,KAAK8lB,OAAO,WAQd,OAJI9lB,MAAKwK,QAAUxK,KAAKoO,IAAIuS,iBAC1Btc,EAASrE,KAAK0rB,mBAAmBrnB,EAAQqtB,IAGpC1xB,KAAK8qB,8BAA8BzmB,EAAQotB,EAAWC,IAI9DhG,mBAAoB,SAASmG,EAAMH,GAClC,GAAII,GAAS,IAiBb,OAhBI9xB,MAAKya,OAAOmM,IAAI5mB,KAAKoO,IAAIyP,WAAY,MACvCiU,EAAS9xB,KAAK2xB,wBAAwBD,GAAU,GAEhD1xB,KAAKwK,QAAUxK,KAAKoO,IAAIoP,UACrBxd,KAAKwK,QAAUxK,KAAKoO,IAAI6F,SAE3B6d,EAAS9xB,KAAKga;AACdha,KAAKya,SAELqX,EAAS9xB,KAAK+lB,OAAO/lB,KAAKoO,IAAIyP,WAAY7d,KAAKoO,IAAIoP,WAEnDxd,KAAKya,QAEQ,MAAXoX,EAAK,KACPA,GAAQ,SAAU,QAASA,KAErB,SAAU,MAAOA,EAAMC,IAGhChH,8BAA+B,SAASzmB,EAAQotB,EAAWC,GAC1DK,EACA,KAAM/xB,KAAKwK,OAASxK,KAAKuO,KACvB,OAAOvO,KAAKwK,OACV,IAAK,IACH,GAAIinB,EACF,MAAOptB,EAEPA,IAAU,OAAQA,EAASrE,KAAKgrB,8BAElC,MACF,KAAK,IACHhrB,KAAKya,MACL,IAAIvW,IAAS,CACTwtB,IACFxtB,EAASlE,KAAKgyB,yBACdhyB,KAAK8lB,OAAO,KAAKrL,QAGE,MAAfza,KAAKwK,OACPtG,EAASlE,KAAKuoB,YACdvoB,KAAK8lB,OAAO,KAAKrL,QAEjBza,KAAKya,OAGTpW,GAAU,SAAUA,EAAQH,EAC5B,MACF,KAAKlE,MAAKoO,IAAIiP,kBACZ,GAAInU,EACJ,QAAOlJ,KAAKya,OAAOjQ,OACjB,IAAKxK,MAAKoO,IAAIoP,SACZtU,GAAQ,SAAUlJ,KAAKga,OACvB,IAAI5L,GAAMpO,KAAKya,OAAOjQ,KAClB4D,KAAQpO,KAAKoO,IAAIyP,WAEnB3U,GAAQ,MAAO,IAAKA,GAAO,MAAOlJ,KAAKga,SACtB,MAAR5L,IAETlF,GAAQ,MAAO,IAAKA,EAAMlJ,KAAKya,OAAO8N,aACtCvoB,KAAK8lB,OAAO,KAAKrL,OAEnB,MACF,KAAKza,MAAKoO,IAAIyP,WACZ3U,GAAQ,MAAOlJ,KAAKga,QACpBha,KAAKya,MACL,MACF,KAAK,IAEHza,KAAKya,OAAOqL,QAAQ,IAAK9lB,KAAKoO,IAAIyP,aACf,MAAf7d,KAAKwK,OAEPtB,EAAOlJ,KAAKya,OAAO8N,YACnBvoB,KAAK8lB,OAAO,KAAKrL,QAGjBvR,EAAOlJ,KAAKuoB,WAEd,MACF,KAAK,IACHrf,EAAOlJ,KAAKya,OAAO8N,YACnBvoB,KAAK8lB,OAAO,KAAKrL;AACjB,KACF,SACEvR,EAAOlJ,KAAK+lB,OAAO/lB,KAAKoO,IAAIoP,SAAUxd,KAAKoO,IAAIyP,aAE/C7d,KAAKya,OAGTpW,GAAU,OAAQA,EAAQ6E,EAC1B,MACF,SACE,KAAM6oB,GAGZ,MAAO1tB,IAKR2tB,uBAAwB,WACvB,GAAI9tB,GAASlE,KAAKoE,MAClB,IAAIpE,KAAKwK,QAAUxK,KAAKoO,IAAIoP,SAAU,CACpC,GAAIxD,GAAOha,KAAKga,OACZiY,EAAyB,MAAZjY,EAAK,EACtBA,GAAOA,EAAK/V,UAAU,EAAG+V,EAAKza,OAAS,GACvC2E,EAASA,EACP,SAAU+tB,EAAYjyB,KAAKuvB,sBAAsBvV,QAE1Cha,MAAKwK,QAAUxK,KAAKoO,IAAIwP,aACjC1Z,EAASA,EAAO,SAAUlE,KAAKga,QACtBha,KAAKwK,QAAUxK,KAAKoO,IAAIyP,WACjC3Z,EAASA,EAAO,WAAYlE,KAAKga,QAEjCha,KAAK8lB,QACH9lB,KAAKoO,IAAIoP,SACTxd,KAAKoO,IAAIwP,aACT5d,KAAKoO,IAAIyP,YAIb,OADA7d,MAAKya,OACEvW,GAaRytB,wBAAyB,SAASD,EAAUzjB,GAE3C,IADA,GAAI5J,GAASrE,KAAKswB,qBAAqBriB,GACjCjO,KAAKwK,OAASxK,KAAKuO,KACvB,GAAkB,KAAdvO,KAAKwK,MAAc,CACrB,GAAIknB,EACFrtB,EAASrE,KAAKya,OAAOuX,6BAChB,CACL,GAAI9tB,GAA+B,MAAtBlE,KAAKya,OAAOjQ,MAAgB,KAAOxK,KAAKwoB,iBACrDnkB,IAAU,SAAUA,EAAQH,GAE9BlE,KAAK8lB,OAAO,KAAKrL,WACZ,CAAA,GAAkB,KAAdza,KAAKwK,OAAiBknB,EAG1B,KAFLrtB,IAAU,SAAUA,EAAQrE,KAAKya,OAAO8N,aACxCvoB,KAAK8lB,OAAO,KAAKrL,OAGrB,MAAOpW,IAORisB,qBAAsB,SAASriB,GAC9B,GAAI5J,GAASrE,KAAKoE,KAAK,WACvB,IAAIpE,KAAK8lB,QAAQ9lB,KAAKoO,IAAIyP,WAAY,MAAMrT,QAAUxK,KAAKoO,IAAIyP,WAE7DxZ,EAASA,EAAOrE,KAAKga,OAAQ/L;AAC7BjO,KAAKya,WACA,CAEL,OAAOza,KAAKya,OAAOjQ,OACjB,IAAK,IACHnG,EAASrE,KAAKya,OAAO8N,YACrBvoB,KAAK8lB,OAAO,KAAKrL,MACjB,MACF,KAAK,IACHpW,GAAU,SAAU,MAAOrE,KAAKswB,sBAAqB,GACrD,MACF,KAAKtwB,MAAKoO,IAAIyP,WACZxZ,GAAU,MAAOrE,KAAKga,QACtBha,KAAKya,MACL,MACF,SACEpW,EAASrE,KAAK+lB,OAAO,IAAK,IAAK/lB,KAAKoO,IAAIyP,aAExC7d,KAAKya,OAETpW,GAAU,SAAU,MAAOA,GAE7B,MAAOA,UAIL6tB,IAAI,SAAS3zB,EAAQkB,EAAOJ,GAQlCI,EAAOJ,SACL6lB,QACEiN,IAAK,kBACLC,IAAK,QACLC,IAAK,4BACLC,IAAK,oBACLC,IAAK,WACLC,IAAK,6BACLC,IAAK,mBACLC,IAAK,eACLC,IAAK,eACLC,IAAK,UACLC,IAAK,UACLC,IAAK,YACLC,IAAK,iBACLC,IAAK,SACLC,IAAK,YACLC,IAAK,iBACLC,IAAK,cACLC,IAAK,iBACLC,IAAK,OACLC,IAAK,OACLC,IAAK,UACLC,IAAK,UACLC,IAAK,OACLC,IAAK,QACLC,IAAK,WACLC,IAAK,UACLC,IAAK,aACLC,IAAK,WACLC,IAAK,WACLC,IAAK,WACLC,IAAK,SACLC,IAAK,gBACLC,IAAK,UACLC,IAAK,YACLC,IAAK,YACLC,IAAK,QACLC,IAAK,UACLC,IAAK,SACLC,IAAK;AACLC,IAAK,UACLC,IAAK,eACLC,IAAK,SACLC,IAAK,UACLC,IAAK,eACLC,IAAK,gBACLC,IAAK,cACLC,IAAK,cACLC,IAAK,iBACLC,IAAK,cACLC,IAAK,cACLC,IAAK,aACLC,IAAK,cACLC,IAAK,aACLC,IAAK,aACLC,IAAK,QACLC,IAAK,QACLC,IAAK,eACLC,IAAK,gBACLC,IAAK,eACLC,IAAK,gBACLC,IAAK,gBACLC,IAAK,OACLC,IAAK,OACLC,IAAK,iBACLC,IAAK,qBACLC,IAAK,aACLC,IAAK,iBACLC,IAAK,wBACLC,IAAK,wBACLC,IAAK,eACLC,IAAK,aACLC,IAAK,gBACLC,IAAK,gBACLC,IAAK,eACLC,IAAK,gBACLC,IAAK,cACLC,IAAK,eACLC,IAAK,SACLC,IAAK,UACLC,IAAK,UACLC,IAAK,eACLC,IAAK,aACLC,IAAK,iBACLC,IAAK,iBACLC,IAAK,UACLC,IAAK,aACLC,IAAK,UACLC,IAAK,aACLC,IAAK,UACLC,IAAK,UACLC,IAAK,YACLC,IAAK,cACLC,IAAK,eACLC,IAAK,QACLC,IAAK,WACLC,IAAK,cACLC,IAAK,YACLC,IAAK;AACLC,IAAK,QACLC,IAAK,cACLC,IAAK,WACLC,IAAK,SACLC,IAAK,cACLC,IAAK,SACLC,IAAK,YACLC,IAAK,WACLC,IAAK,eACLC,IAAK,aACLC,IAAK,6BACLC,IAAK,YACLC,IAAK,YACLC,IAAK,SACLC,IAAK,SACLC,IAAK,QACLC,IAAK,YACLC,IAAK,aACLC,IAAK,WACLC,IAAK,SACLC,IAAK,kBACLC,IAAK,gBACLC,IAAK,YACLC,IAAK,aACLC,IAAK,aACLC,IAAK,uBACLC,IAAK,cACLC,IAAK,eACLC,IAAK,YACLC,IAAK,gBACLC,IAAK,aACLC,IAAK,aACLC,IAAK,QACLC,IAAK,cACLC,IAAK,eAEPjsB,OACE8H,gBAAiB,IACjBV,MAAO,IACPoI,0BAA2B,IAC3BT,kBAAmB,IACnBG,SAAU,IACV8B,2BAA4B,IAC5B5B,iBAAkB,IAClB8B,aAAc,IACd5B,aAAc,IACd5H,QAAS,IACTE,QAAS,IACTjB,UAAW,IACXE,eAAgB,IAChBJ,OAAQ,IACRK,UAAW,IACXE,eAAgB,IAChBE,YAAa,IACb+K,eAAgB,IAChB1N,KAAM,IACN5B,KAAM,IACNI,QAAS,IACTI,QAAS,IACTI,KAAM,IACNE,MAAO,IACPgB,SAAU,IACVQ,QAAS,IACTE,WAAY,IACZlD,SAAU;AACVuF,SAAU,IACVQ,SAAU,IACVzC,OAAQ,IACRuI,cAAe,IACflF,QAAS,IACT/E,UAAW,IACXI,UAAW,IACX9B,MAAO,IACPM,QAAS,IACT4C,OAAQ,IACR9C,UAAW,IACXF,QAAS,IACT8B,aAAc,IACd2E,OAAQ,IACRzC,QAAS,IACT6M,aAAc,IACdnB,cAAe,IACfmC,YAAa,IACb/B,YAAa,IACbmC,eAAgB,IAChBG,YAAa,IACbE,YAAa,IACbG,WAAY,IACZG,YAAa,IACbxB,WAAY,IACZM,WAAY,IACZd,MAAO,IACPnB,MAAO,IACPiD,aAAc,IACdH,cAAe,IACfzL,aAAc,IACdE,cAAe,IACfE,cAAe,IACfmK,KAAM,IACNM,KAAM,IACNlB,eAAgB,IAChBM,mBAAoB,IACpBL,WAAY,IACZM,eAAgB,IAChBO,sBAAuB,IACvBE,sBAAuB,IACvBzP,aAAc,IACdqF,WAAY,IACZG,cAAe,IACfI,cAAe,IACfE,aAAc,IACdE,cAAe,IACfE,YAAa,IACbE,aAAc,IACd/I,OAAQ,IACR+D,QAAS,IACT+L,QAAS,IACTD,aAAc,IACd1P,WAAY,IACZgR,eAAgB,IAChBR,eAAgB,IAChBtJ,QAAS,IACTE,WAAY,IACZtD,QAAS,IACTuC,WAAY,IACZnC,QAAS,IACTqC,QAAS,IACTpC,UAAW,IACXH,YAAa,IACbI,aAAc,IACdM,MAAO,IACPmC,SAAU,IACVF,YAAa;AACbF,UAAW,IACXvG,QAAS,IACToE,MAAO,IACPmB,YAAa,IACbzE,SAAU,IACVI,OAAQ,IACR0B,YAAa,IACbE,OAAQ,IACRE,UAAW,IACXpB,SAAU,IACVI,aAAc,IACdV,WAAY,IACZwM,2BAA4B,IAC5BlB,UAAW,IACXD,UAAW,IACXxN,OAAQ,IACRE,OAAQ,IACRE,MAAO,IACPV,UAAW,IACXI,WAAY,IACZF,SAAU,IACVU,OAAQ,IACRkP,gBAAiB,IACjBI,cAAe,IACfpQ,UAAW,IACX6O,WAAY,IACZhD,WAAY,IACZC,qBAAsB,IACtBwD,YAAa,IACb5D,aAAc,IACdC,UAAW,IACXC,cAAe,IACfiI,WAAY,IACZhB,WAAY,IACZa,MAAO,IACPD,YAAa,IACbR,YAAa,WAIXuY,cAAc,SAASj8B,EAAQkB,EAAOJ,GAe5C,QAASo7B,GAAQ12B,EAAK22B,GAGpB,IAFA,GAAIC,GAAOr2B,OAAOq2B,KAAK52B,GACnB/E,EAAI27B,EAAKp7B,OACNP,KAAK,CACV,GAAIoc,GAAIuf,EAAK37B,GACTgrB,EAAMjmB,EAAIqX,EACF,QAAR4O,QACK0Q,GAAGtf,GACc,kBAAR4O,GAChB0Q,EAAGtf,GAAK4O,EAAI4Q,KAAKF,GACRr5B,MAAMiK,QAAQ0e,GACvB0Q,EAAGtf,GAAK/Z,MAAMiK,QAAQovB,EAAGtf,IAAMsf,EAAGtf,GAAG3a,OAAOupB,GAAOA,EAC3B,gBAARA,GAChB0Q,EAAGtf,GAAsB,gBAAVsf,GAAGtf,GAAkBqf,EAAQzQ,EAAK0Q,EAAGtf,IAAM4O,EAE1D0Q,EAAGtf,GAAK4O,EAGZ,MAAO0Q,GA1BT,GAAIn3B,GAAQhF,EAAQ,WAChB8E,EAAS9E,EAAQ,YACjB8P,EAAS9P,EAAQ,YACjByE,EAAMzE,EAAQ,SAkCd4P,EAAS,SAASsiB,GACpB,MAAoB,kBAATzwB,MACF,GAAIA,MAAKywB,IAElBzwB,KAAKqO,OAASA,EACdrO,KAAKuD,MAAQ,GAAIA,GAAMvD,MACvBA,KAAKikB,IAAM,GAAIjhB;AACfhD,KAAKqD,OAAS,GAAIA,GAAOrD,KAAKuD,MAAOvD,KAAKikB,UACtCwM,GAA8B,gBAAZA,IACpBgK,EAAQhK,EAASzwB,QASrBmO,GAAO5J,OAAS,SAASksB,GACvB,MAAO,IAAItiB,GAAOsiB,IAMpBtiB,EAAO0sB,UAAY,SAASC,EAAQrK,GAClC,GAAI7sB,GAAO,GAAIuK,GAAOsiB,EACtB,OAAO7sB,GAAKi3B,UAAUC,IAOxB3sB,EAAO3M,UAAUq5B,UAAY,SAASC,GAGpC,MAFA96B,MAAKuD,MAAMmL,WAAY,EACvB1O,KAAKuD,MAAMiL,YAAa,EACjBxO,KAAKqD,OAAO8hB,MAAM2V,IAM3B3sB,EAAO4sB,UAAY,SAASD,EAAQrK,GAClC,GAAI7sB,GAAO,GAAIuK,GAAOsiB,EACtB,OAAO7sB,GAAKm3B,UAAUD,IAMxB3sB,EAAO3M,UAAUu5B,UAAY,SAASD,GAGpC,MAFA96B,MAAKuD,MAAMmL,WAAY,EACvB1O,KAAKuD,MAAMiL,YAAa,EACjBxO,KAAKqD,OAAO8hB,MAAM2V,IAM3B3sB,EAAO6sB,YAAc,SAASF,EAAQrK,GACpC,GAAI7sB,GAAO,GAAIuK,GAAOsiB,EACtB,OAAO7sB,GAAKo3B,YAAYF,IAM1B3sB,EAAO3M,UAAUw5B,YAAc,SAASF,GACtC96B,KAAKuD,MAAMmL,WAAY,EACvB1O,KAAKuD,MAAMiL,YAAa,CACxB,IAAID,GAAMvO,KAAKuD,MAAMgL,IACjBD,EAAQtO,KAAKqO,OAAO6W,MACxBllB,MAAKuD,MAAMyV,SAAS8hB,EAGpB,KAFA,GAAItwB,GAAQxK,KAAKuD,MAAMiX,OAASjM,EAC5BlK,KACEmG,GAAS+D,GAAK,CAClB,GAAI0sB,GAAQj7B,KAAKuD,MAAM6V,MACnB9K,GAAM4sB,eAAe1wB,KACvBywB,GAAS3sB,EAAM9D,GAAQywB,EAAOj7B,KAAKuD,MAAMC,OAAOC,aAElDY,EAAO9C,KAAK05B,GACZzwB,EAAQxK,KAAKuD,MAAMiX,OAASjM,EAE9B,MAAOlK,IAIT5E,EAAOJ,QAAU8O,IAEdgtB,QAAQ,EAAEC,UAAU,GAAGC,WAAW,GAAGC,WAAW","file":"php-parser.min.js"} +{"version":3,"sources":["php-parser.js"],"names":["require","e","t","n","r","s","o","u","a","i","f","Error","code","l","exports","call","length","1","module","defaultSetTimout","defaultClearTimeout","runTimeout","fun","cachedSetTimeout","setTimeout","this","runClearTimeout","marker","cachedClearTimeout","clearTimeout","cleanUpNextTick","draining","currentQueue","queue","concat","queueIndex","drainQueue","timeout","len","run","Item","array","noop","process","nextTick","args","Array","arguments","push","prototype","apply","title","browser","env","argv","version","versions","on","addListener","once","off","removeListener","removeAllListeners","emit","binding","name","cwd","chdir","dir","umask","2","Location","Position","AST","withPositions","withSource","prepare","kind","parser","start","lexer","yylloc","first_line","first_column","first_offset","self","location","slice","src","_input","substring","offset","shift","node","result","Object","create","forEach","ctor","constructor","toLowerCase","./ast/array","./ast/assign","./ast/block","./ast/boolean","./ast/break","./ast/case","./ast/class","./ast/classconstant","./ast/clone","./ast/coalesce","./ast/constant","./ast/constref","./ast/continue","./ast/do","./ast/doc","./ast/echo","./ast/empty","./ast/entry","./ast/error","./ast/eval","./ast/exit","./ast/for","./ast/foreach","./ast/function","./ast/goto","./ast/identifier","./ast/if","./ast/include","./ast/inline","./ast/interface","./ast/isset","./ast/label","./ast/list","./ast/literal","./ast/location","./ast/magic","./ast/method","./ast/namespace","./ast/number","./ast/parameter","./ast/position","./ast/post","./ast/print","./ast/program","./ast/property","./ast/return","./ast/shell","./ast/string","./ast/switch","./ast/trait","./ast/traitalias","./ast/traitprecedence","./ast/traituse","./ast/unset","./ast/variable","./ast/while","3","Expr","KIND","extends","shortForm","items","./expression","4","Statement","Assign","left","right","operator","./statement","5","Block","children","6","Literal","Boolean","value","./literal","7","Node","Break","./node","8","Case","test","body","9","Declaration","Class","ext","impl","flags","isAnonymous","implements","parseFlags","./declaration","10","Constant","ClassConstant","./constant","11","Clone","what","12","Coalesce","ifnull","13","14","ConstRef","identifier","15","Continue","16","IS_PUBLIC","IS_PROTECTED","IS_PRIVATE","isAbstract","isFinal","visibility","isStatic","17","Do","18","Doc","isDoc","lines","19","Sys","Echo","./sys","20","Empty","21","Entry","key","22","message","token","line","expected","23","Eval","source","24","Exit","status","25","Expression","26","For","init","increment","27","Foreach","28","fn","byref","type","29","Goto","label","30","Identifier","fqn","isArray","join","31","If","alternate","32","Include","target","33","Inline","34","Interface","35","Isset","36","Label","37","List","38","39","end","40","Magic","41","Method","./function","42","Namespace","withBrackets","./block","./identifier","43","loc","44","_Number","45","Operation","46","Parameter","isRef","isVariadic","variadic","47","column","48","Post","./operation","49","Print","50","Program","errors","51","Property","52","Return","expr","53","Shell","54","55","String","isDoubleQuote","56","Switch","57","58","Trait","59","TraitAlias","trait","method","as","60","TraitPrecedence","instead","61","TraitUse","traits","adaptations","62","Unset","63","Variable","64","While","65","engine","tok","tokens","names","EOF","all_tokens","comment_tokens","mode_eval","asp_tags","short_tags","yyprevcol","keywords","__class__","T_CLASS_C","__trait__","T_TRAIT_C","__function__","T_FUNC_C","__method__","T_METHOD_C","__line__","T_LINE","__file__","T_FILE","__dir__","T_DIR","__namespace__","T_NS_C","exit","T_EXIT","die","function","T_FUNCTION","const","T_CONST","return","T_RETURN","try","T_TRY","catch","T_CATCH","finally","T_FINALLY","throw","T_THROW","if","T_IF","elseif","T_ELSEIF","endif","T_ENDIF","else","T_ELSE","while","T_WHILE","endwhile","T_ENDWHILE","do","T_DO","for","T_FOR","endfor","T_ENDFOR","foreach","T_FOREACH","endforeach","T_ENDFOREACH","declare","T_DECLARE","enddeclare","T_ENDDECLARE","instanceof","T_INSTANCEOF","T_AS","switch","T_SWITCH","endswitch","T_ENDSWITCH","case","T_CASE","default","T_DEFAULT","break","T_BREAK","continue","T_CONTINUE","goto","T_GOTO","echo","T_ECHO","print","T_PRINT","class","T_CLASS","interface","T_INTERFACE","T_TRAIT","T_EXTENDS","T_IMPLEMENTS","new","T_NEW","clone","T_CLONE","var","T_VAR","eval","T_EVAL","include","T_INCLUDE","include_once","T_INCLUDE_ONCE","T_REQUIRE","require_once","T_REQUIRE_ONCE","namespace","T_NAMESPACE","use","T_USE","insteadof","T_INSTEADOF","global","T_GLOBAL","isset","T_ISSET","empty","T_EMPTY","__halt_compiler","T_HALT_COMPILER","static","T_STATIC","abstract","T_ABSTRACT","final","T_FINAL","private","T_PRIVATE","protected","T_PROTECTED","public","T_PUBLIC","unset","T_UNSET","list","T_LIST","T_ARRAY","callable","T_CALLABLE","or","T_LOGICAL_OR","and","T_LOGICAL_AND","xor","T_LOGICAL_XOR","castKeywords","int","T_INT_CAST","integer","real","T_DOUBLE_CAST","double","float","string","T_STRING_CAST","binary","T_ARRAY_CAST","object","T_OBJECT_CAST","bool","T_BOOL_CAST","boolean","T_UNSET_CAST","setInput","input","size","yylineno","yytext","last_line","last_column","conditionStack","done","begin","ch","unput","last_col","first_col","c","tryMatch","text","ahead","tryMatchCaseless","consume","getState","setState","state","appendToken","lex","next","T_WHITESPACE","T_COMMENT","T_DOC_COMMENT","T_OPEN_TAG","T_OPEN_TAG_WITH_ECHO","condition","curCondition","stateCb","popState","pop","k","./lexer/comments.js","./lexer/initial.js","./lexer/numbers.js","./lexer/property.js","./lexer/scripting.js","./lexer/strings.js","./lexer/tokens.js","./lexer/utils.js","66","aspTagMode","tthis","is_WHITESPACE","67","nextINITIAL","matchINITIAL","T_INLINE_HTML","68","arch","MAX_LENGTH_OF_LONG","long_min_digits","consume_NUM","hasPoint","is_HEX","consume_HNUM","consume_BNUM","is_NUM","consume_LNUM","T_DNUMBER","T_LNUMBER","_process","69","matchST_LOOKING_FOR_PROPERTY","T_OBJECT_OPERATOR","is_LABEL_START","consume_LABEL","T_STRING","matchST_LOOKING_FOR_VARNAME","T_STRING_VARNAME","matchST_VAR_OFFSET","T_NUM_STRING","T_VARIABLE","T_ENCAPSED_AND_WHITESPACE","is_TOKEN","70","matchST_IN_SCRIPTING","consume_TOKEN","T_CONSTANT_ENCAPSED_STRING","ST_DOUBLE_QUOTES","nextCH","T_CLOSE_TAG","71","is_HEREDOC","revert","is_TABSPACE","tChar","yyoffset","is_LABEL","yylabel","heredoc_label","T_START_HEREDOC","prefix","isDOC_MATCH","matchST_NOWDOC","T_END_HEREDOC","matchST_HEREDOC","T_DOLLAR_OPEN_CURLY_BRACES","consume_VARIABLE","T_CURLY_OPEN","matchST_BACKQUOTE","matchST_DOUBLE_QUOTES","72","id","T_YIELD_FROM","T_YIELD","tokenTerminals","$","-","nchar","T_DEC","T_MINUS_EQUAL","\\","T_NS_SEPARATOR","/","T_DIV_EQUAL",":","T_DOUBLE_COLON","(","initial","consume_TABSPACE","yylen","castToken","castId","=","T_DOUBLE_ARROW","T_IS_IDENTICAL","T_IS_EQUAL","+","T_INC","T_PLUS_EQUAL","!","T_IS_NOT_IDENTICAL","T_IS_NOT_EQUAL","?","T_COALESCE","<","T_SL_EQUAL","T_SL","T_SPACESHIP","T_IS_SMALLER_OR_EQUAL",">","T_IS_GREATER_OR_EQUAL","T_SR_EQUAL","T_SR","*","T_MUL_EQUAL","T_POW_EQUAL","T_POW",".","T_CONCAT_EQUAL","T_ELLIPSIS","%","T_MOD_EQUAL","&","T_AND_EQUAL","T_BOOLEAN_AND","|","T_OR_EQUAL","T_BOOLEAN_OR","^","T_XOR_EQUAL","73","charCodeAt","indexOf","is_NEWLINE","74","isNumber","isNaN","parseFloat","isFinite","ast","_gracefulProxy","_graceful","prev","debug","extractDoc","suppressErrors","lastError","startAt","entries","SCALAR","T_MAGIC_CONST","T_MEMBER_FLAGS","VARIABLE","EOS","EXPR","getTokenName","values","parse","_errors","currentNamespace","innerList","program","childs","nextWithComments","read_start","undefined","raiseError","msgExpect","expect","error","msg","symbol","expectEndOfStatement","ignoreStack","showlog","stack","split","trim","found","console","log","ignoreComments","is","read_token","./parser/array.js","./parser/class.js","./parser/comment.js","./parser/expr.js","./parser/function.js","./parser/if.js","./parser/loops.js","./parser/main.js","./parser/namespace.js","./parser/scalar.js","./parser/statement.js","./parser/switch.js","./parser/try.js","./parser/utils.js","./parser/variable.js","75","ArrayExpr","ArrayEntry","read_array","read_array_pair_list","read_variable","read_expr","read_dim_offset","76","read_class","flag","propName","propExtends","propImplements","read_namespace_name","read_name_list","read_class_body","read_class_scope","read_member_flags","variables","read_variable_list","read_function","constants","read_constant_list","read_trait_use_statement","read_doc_comment","read_comment","read_list","asInterface","idx","val","read_interface","read_interface_body","read_function_declaration","read_trait","read_trait_use_alias","alias","77","docSplit","78","read_expr_item","trueArg","recursive_variable_chain_scan","read_dereferencable","read_function_argument_list","read_encapsed_string","assign","isInner","assignList","read_assignment_list","hasItem","read_new_expr","arg","read_scalar","read_class_name_reference","read_static_getter","read_assignment_list_element","79","is_reference","is_variadic","closure","read_code_block","nodeName","returnType","params","read_parameter_list","read_lexical_var","read_type","read_parameter","read_argument_list","80","read_if","read_if_expr","read_elseif_short","read_else_short","read_inner_statement","read_statement","81","read_while","read_short_form","read_do","read_for","read_foreach","read_foreach_variable","82","read_namespace","read_top_statement","83","read_top_statements","read_use_statements","read_use_statement_mixed","item","read_inline_use_declaration","ns","read_use_statement","ignoreType","84","specialChar","\\r","\\n","\\t","\\v","fromCharCode","\\e","\\f","\\\\","\\$","\\\"","\\'","resolve_special_chars","replace","seq","get_magic_constant","isBinCast","err","read_encapsed_string_item","first","85","statement","read_const_list","read_inner_statements","read_declare_list","read_switch","read_simple_variable","current","withParanthesis","options","read_try","top","86","read_switch_case_list","read_case_list","stopToken","87","allways","catches","exName","varName","exception","88","separator","preserveFirstSeparator","89","read_only","encapsed","read_reference_variable","literal","from","getter","recursive_scan_loop","read_encaps_var_offset","isDblQuote","90","101","102","103","104","105","106","107","108","109","110","111","112","113","114","115","116","117","118","119","120","121","122","123","124","125","126","127","128","129","130","131","132","133","134","135","136","137","138","139","140","141","142","143","144","145","146","147","148","149","150","151","152","153","154","155","156","157","158","159","160","161","162","163","164","165","166","167","168","169","170","171","172","173","174","175","176","177","178","179","180","181","182","183","184","185","186","187","188","189","190","191","192","193","194","195","196","197","198","199","200","201","202","203","204","205","206","207","208","209","210","211","212","213","214","215","216","217","218","219","220","221","222","223","224","225","226","227","228","229","230","231","232","233","php-parser","combine","to","keys","bind","parseEval","buffer","parseCode","tokenGetAll","entry","hasOwnProperty","./ast","./lexer","./parser","./tokens"],"mappings":"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","file":"php-parser.min.js"} \ No newline at end of file diff --git a/docs/AST.md b/docs/AST.md index 9cf4ef441..31d9cc893 100644 --- a/docs/AST.md +++ b/docs/AST.md @@ -4,8 +4,34 @@ ## Class hierarchy +- [Location](#location) +- [Position](#position) - [Node](#Node) + - [Identifier](#identifier) + - [TraitUse](#traituse) + - [TraitAlias](#traitalias) + - [TraitPrecedence](#traitprecedence) + - [Entry](#entry) + - [Case](#case) + - [Label](#label) + - [Doc](#doc) + - [Error](#error) - [Expression](#expression) + - [Array](#array) + - [Variable](#variable) + - [ConstRef](#constref) + - [Lookup](#lookup) + - [PropertyLookup](#propertylookup) + - [StaticLookup](#staticlookup) + - [OffsetLookup](#offsetlookup) + - [Operation](#operation) + - [Coalesce](#coalesce) + - [Pre](#pre) + - [Post](#post) + - [Bin](#bin) + - [Bool](#Bool) + - [Unary](#unary) + - [Cast](#cast) - [Literal](#literal) - [Boolean](#boolean) - [String](#string) @@ -13,38 +39,49 @@ - [Inline](#inline) - [Magic](#magic) - [Shell](#shell) - - [Array](#array) - - [Variable](#variable) - [Statement](#statement) + - [Eval](#eval) + - [Exit](#exit) + - [Clone](#clone) + - [Global](#global) + - [Include](#include) + - [Assign](#assign) + - [RetIf](#retif) + - [If](#if) + - [Do](#do) + - [While](#while) + - [For](#for) + - [Foreach](#foreach) + - [Switch](#switch) + - [Goto](#goto) + - [Silent](#silent) + - [Try](#try) + - [Catch](#catch) + - [Call](#call) + - [Closure](#closure) + - [New](#new) + - [UseGroup](#usegroup) + - [UseItem](#useitem) - [Block](#block) - [Program](#program) - [Namespace](#namespace) - [Sys](#sys) - [Echo](#echo) + - [List](#list) - [Print](#print) - [Isset](#isset) - [Unset](#unset) - [Empty](#empty) - [Declaration](#declaration) - [Class](#class) + - [Interface](#interface) + - [Trait](#trait) - [Constant](#constant) - [ClassConstant](#classconstant) - [Function](#function) - [Method](#method) - [Parameter](#parameter) - [Property](#property) - - [Eval](#eval) - - [Exit](#exit) - - [Clone](#clone) - - [Coalesce](#coalesce) - - [Include](#include) - - [Assign](#assign) - - [Identifier](#identifier) - - [Entry](#entry) - - [Documentation](#documentation) - - [Error](#error) -- [Location](#location) -- [Position](#position) * * * @@ -53,6 +90,18 @@ - `withPositions` - `withSource` +## position + +Create a position node from specified parser +including it's lexer current state + +**Parameters** + +- `Parser` +- `parser` + +Returns **[Position](#position)** + ## prepare Prepares an AST node @@ -79,6 +128,18 @@ The AST builder class - `withPositions` **[Boolean](#boolean)** Should locate any node (by default false) - `withSource` **[Boolean](#boolean)** Should extract the node original code (by default false) +## position + +Create a position node from specified parser +including it's lexer current state + +**Parameters** + +- `Parser` +- `parser` + +Returns **[Position](#position)** + ## prepare Prepares an AST node @@ -114,6 +175,18 @@ Assigns a value to the specified target - `right` **[Expression](#expression)** - `operator` **[String](#string)** +# Bin + +**Extends Operation** + +Binary operations + +**Properties** + +- `type` **[String](#string)** +- `left` **[Expression](#expression)** +- `right` **[Expression](#expression)** + # Block **Extends Statement** @@ -124,12 +197,86 @@ A block statement, i.e., a sequence of statements surrounded by braces. - `children` **[Array](#array)<[Node](#node)>** +# Bool + +**Extends Operation** + +Boolean operations + +**Properties** + +- `type` **[String](#string)** +- `left` **[Expression](#expression)** +- `right` **[Expression](#expression)** + # Boolean **Extends Literal** Defines a boolean value (true/false) +# Break + +**Extends Node** + +A break statement + +# Call + +**Extends Statement** + +Executes a call statement + +**Properties** + +- `arguments` **[Array](#array)<Arguments>** + +# Case + +**Extends Node** + +A switch case statement + +**Properties** + +- `test` **([Expression](#expression) | null)** if null, means that the default case +- `body` **([Block](#block) | null)** + +# Cast + +**Extends Operation** + +Binary operations + +**Properties** + +- `type` **[String](#string)** +- `what` **[Expression](#expression)** + +# Try + +**Extends Statement** + +Defines a catch statement + +**Properties** + +- `what` **[Array](#array)<[Identifier](#identifier)>** +- `variable` **[Variable](#variable)** +- `body` **[Statement](#statement)** + +# Try + +**Extends Statement** + +Defines a try statement + +**Properties** + +- `body` **[Block](#block)** +- `catches` **[Array](#array)<Catch>** +- `allways` **[Block](#block)** + # Class **Extends Declaration** @@ -144,7 +291,6 @@ A class definition - `isAnonymous` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** - `isAbstract` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** - `isFinal` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** -- `isFinal` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** # ClassConstant @@ -167,10 +313,24 @@ Defines a clone call - `what` **[Expression](#expression)** -# Coalesce +# Closure **Extends Statement** +Defines a closure + +**Properties** + +- `arguments` **[Array](#array)<[Parameter](#parameter)>** +- `type` **[Identifier](#identifier)** +- `byref` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** +- `nullable` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** +- `body` **([Block](#block) | null)** + +# Coalesce + +**Extends Operation** + Verify is the test property is defined and is not null, and returns is, otherwise returns the ifnull expression. @@ -189,6 +349,22 @@ Defines a namespace constant - `value` **([Node](#node) | null)** +# ConstRef + +**Extends Expression** + +A constant reference + +**Properties** + +- `name` **([String](#string) \| [Node](#node))** + +# Continue + +**Extends Node** + +A continue statement + # Declaration **Extends Statement** @@ -209,6 +385,17 @@ Generic flags parser Returns **void** +# Do + +**Extends Statement** + +Defines a do/while statement + +**Properties** + +- `test` **[Expression](#expression)** +- `body` **[Statement](#statement)** + # Documentation **Extends Node** @@ -218,7 +405,7 @@ A comment or documentation **Properties** - `isDoc` **[Boolean](#boolean)** -- `text` **[String](#string)** +- `lines` **[Array](#array)<[String](#string)>** # Echo @@ -283,6 +470,34 @@ Defines an exit / die call Any expression node. Since the left-hand side of an assignment may be any expression in general, an expression can also be a pattern. +# For + +**Extends Statement** + +Defines a for iterator + +**Properties** + +- `init` **[Array](#array)<[Expression](#expression)>** +- `test` **[Array](#array)<[Expression](#expression)>** +- `increment` **[Array](#array)<[Expression](#expression)>** +- `body` **[Statement](#statement)** +- `shortForm` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** + +# Foreach + +**Extends Statement** + +Defines a foreach iterator + +**Properties** + +- `source` **[Expression](#expression)** +- `key` **([Expression](#expression) | null)** +- `value` **[Expression](#expression)** +- `body` **[Statement](#statement)** +- `shortForm` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** + # Function **Extends Declaration** @@ -291,10 +506,31 @@ Defines a classic function **Properties** -- `arguments` **[Array](#array)<Argument>** +- `arguments` **[Array](#array)<[Parameter](#parameter)>** - `type` **[Identifier](#identifier)** - `byref` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** -- `children` **[Array](#array)<[Node](#node)>** +- `nullable` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** +- `body` **([Block](#block) | null)** + +# Global + +**Extends Statement** + +Imports a variable from the global scope + +**Properties** + +- `items` **[Array](#array)<[Variable](#variable)>** + +# Goto + +**Extends Statement** + +Defines goto statement + +**Properties** + +- `label` **[String](#string)** # Identifier @@ -305,7 +541,46 @@ Defines an identifier node **Properties** - `name` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** -- `fqn` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** +- `resolution` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** + +## UNQUALIFIED_NAME + +This is an identifier without a namespace separator, such as Foo + +Type: [String](#string) + +## QUALIFIED_NAME + +This is an identifier with a namespace separator, such as Foo\\Bar + +Type: [String](#string) + +## FULL_QUALIFIED_NAME + +This is an identifier with a namespace separator that begins with +a namespace separator, such as \\Foo\\Bar. The namespace \\Foo is also +a fully qualified name. + +Type: [String](#string) + +## RELATIVE_NAME + +This is an identifier starting with namespace, such as namespace\\Foo\\Bar. + +Type: [String](#string) + +# If + +**Extends Statement** + +Defines a if statement + +**Properties** + +- `test` **[Expression](#expression)** +- `body` **[Block](#block)** +- `alternate` **([Block](#block) \| [If](#if) | null)** +- `shortForm` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** # Include @@ -325,13 +600,40 @@ Defines system include call Defines inline html output (treated as echo output) +# Interface + +**Extends Declaration** + +An interface definition + +**Properties** + +- `extends` **[Array](#array)<[Identifier](#identifier)>** +- `body` **[Array](#array)<[Declaration](#declaration)>** + # Isset **Extends Sys** Defines an isset call -# ArrayExpression +# Label + +**Extends Node** + +A label statement (referenced by goto) + +**Properties** + +- `name` **[String](#string)** + +# List + +**Extends Sys** + +Defines list assignment + +# Literal **Extends Expression** @@ -357,6 +659,17 @@ Defines the location of the node (with it's source contents as string) - `start` **[Position](#position)** - `end` **[Position](#position)** +# Lookup + +**Extends Expression** + +Lookup on an offset in the specified object + +**Properties** + +- `what` **[Expression](#expression)** +- `offset` **[Expression](#expression)** + # Magic **Extends Literal** @@ -387,6 +700,17 @@ The main program node - `name` **[Identifier](#identifier)** - `withBrackets` **[Boolean](#boolean)** +# New + +**Extends Statement** + +Creates a new instance of the specified class + +**Properties** + +- `what` **([Identifier](#identifier) \| [Variable](#variable) \| [Class](#class))** +- `arguments` **[Array](#array)<Arguments>** + # Node A generic AST node @@ -417,6 +741,18 @@ Returns **[Function](#function)** Defines a numeric value +# OffsetLookup + +**Extends Lookup** + +Lookup on an offset in an array + +# Operation + +**Extends Expression** + +Defines binary operations + # Parameter **Extends Declaration** @@ -429,6 +765,7 @@ Defines a function parameter - `value` **([Node](#node) | null)** - `byref` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** - `variadic` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** +- `nullable` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** # Position @@ -446,6 +783,28 @@ Each Position object consists of a line number (1-indexed) and a column number ( - `column` **[Number](#number)** - `offset` **[Number](#number)** +# Post + +**Extends Operation** + +Defines a post operation `$i++` or `$i--` + +**Properties** + +- `type` **[String](#string)** +- `what` **[Variable](#variable)** + +# Pre + +**Extends Operation** + +Defines a pre operation `++$i` or `--$i` + +**Properties** + +- `type` **[String](#string)** +- `what` **[Variable](#variable)** + # Print **Extends Sys** @@ -475,18 +834,62 @@ Defines a class property - `visibility` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** - `value` **([Node](#node) | null)** +# PropertyLookup + +**Extends Lookup** + +Lookup to an object property + +# RetIf + +**Extends Statement** + +Defines a short if statement that returns a value + +**Properties** + +- `test` **[Expression](#expression)** +- `trueExpr` **[Expression](#expression)** +- `falseExpr` **[Expression](#expression)** + +# Return + +**Extends Node** + +A continue statement + +**Properties** + +- `expr` **([Expression](#expression) | null)** + # Shell **Extends Literal** Defines inline html output (treated as echo output) +# Silent + +**Extends Statement** + +Avoids to show/log warnings & notices from the inner expression + +**Properties** + +- `expr` **[Expression](#expression)** + # Statement **Extends Node** Any statement. +# StaticLookup + +**Extends Lookup** + +Lookup to a static property + # String **Extends Literal** @@ -497,6 +900,18 @@ Defines inline html output (treated as echo output) - `isDoubleQuote` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** +# Switch + +**Extends Statement** + +Defines a switch statement + +**Properties** + +- `test` **[Expression](#expression)** +- `body` **[Block](#block)** +- `shortForm` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** + # Sys **Extends Statement** @@ -507,12 +922,107 @@ Defines system based call - `arguments` **[Array](#array)<[Node](#node)>** +# Trait + +**Extends Declaration** + +A trait definition + +**Properties** + +- `extends` **([Identifier](#identifier) | null)** +- `implements` **[Array](#array)<[Identifier](#identifier)>** +- `body` **[Array](#array)<[Declaration](#declaration)>** + +# TraitAlias + +**Extends Node** + +Defines a trait alias + +**Properties** + +- `trait` **([Identifier](#identifier) | null)** +- `method` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** +- `as` **([string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) | null)** +- `visibility` **([string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) | null)** + +# TraitPrecedence + +**Extends Node** + +Defines a trait alias + +**Properties** + +- `trait` **([Identifier](#identifier) | null)** +- `method` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** +- `instead` **[Array](#array)<[Identifier](#identifier)>** + +# TraitUse + +**Extends Node** + +Defines a trait usage + +**Properties** + +- `traits` **[Array](#array)<[Identifier](#identifier)>** +- `adaptations` **([Array](#array)<[Node](#node)> | null)** + +# Unary + +**Extends Operation** + +Unary operations + +**Properties** + +- `type` **[String](#string)** +- `what` **[Expression](#expression)** + # Unset **Extends Sys** Deletes references to a list of variables +# UseGroup + +**Extends Statement** + +Defines a use statement (with a list of use items) + +**Properties** + +- `name` **([Identifier](#identifier) | null)** +- `type` **([String](#string) | null)** Possible value : function, const +- `item` **[Array](#array)<[UseItem](#useitem)>** + +# UseItem + +**Extends Statement** + +Defines a use statement (from namespace) + +**Properties** + +- `name` **[Identifier](#identifier)** +- `type` **([String](#string) | null)** Possible value : function, const +- `alias` **([String](#string) | null)** + +## TYPE_CONST + +Importing a constant + +Type: [String](#string) + +## TYPE_FUNC + +Importing a function + +Type: [String](#string) + # Variable **Extends Expression** @@ -522,5 +1032,17 @@ be any expression in general, an expression can also be a pattern. **Properties** -- `identifier` **([String](#string) \| [Node](#node))** +- `name` **([String](#string) \| [Node](#node))** - `byref` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** + +# While + +**Extends Statement** + +Defines a while statement + +**Properties** + +- `test` **[Expression](#expression)** +- `body` **[Statement](#statement)** +- `shortForm` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** diff --git a/docs/README.md b/docs/README.md index 5bf4e18da..8c6ec8ff1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -12,7 +12,7 @@ Type: Engine - `lexer` **Lexer** - `parser` **Parser** -- `ast` **[AST](#ast)** +- `ast` **AST** - `tokens` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** ## parseEval @@ -23,7 +23,7 @@ parsing eval string as '$x = 1;' - `buffer` -Returns **[Array](#array)** +Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)** ## parseCode @@ -77,1227 +77,3 @@ split the buffer into tokens - `buffer` - `options` - -# lexer - -This is the php lexer. It will tokenize the string for helping the -parser to build the AST from its grammar. - -**Parameters** - -- `engine` - -**Properties** - -- `EOF` **Integer** -- `all_tokens` **[Boolean](#boolean)** defines if all tokens must be retrieved (used by token_get_all only) -- `comment_tokens` **[Boolean](#boolean)** extracts comments tokens -- `mode_eval` **[Boolean](#boolean)** enables the evald mode (ignore opening tags) -- `asp_tags` **[Boolean](#boolean)** disables by default asp tags mode -- `short_tags` **[Boolean](#boolean)** enables by default short tags mode -- `keywords` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** List of php keyword -- `castKeywords` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** List of php keywords for type casting - -## setInput - -Initialize the lexer with the specified input - -**Parameters** - -- `input` - -## input - -consumes and returns one char from the input - -**Parameters** - -- `size` - -## unput - -revert eating specified size - -**Parameters** - -- `size` - -## getState - -Gets the current state - -## setState - -Sets the current lexer state - -**Parameters** - -- `state` - -# T_DOC_COMMENT - -Behaviour : - -# T_END_HEREDOC - -edge case : empty now doc \* - -# ch - -SCANNING CONTENTS \* - -# ch - -edge case : empty here doc \* - -# ch - -SCANNING CONTENTS \* - -# parser - -The PHP Parser class - -**Parameters** - -- `lexer` -- `ast` - -**Properties** - -- `EOF` **Integer** -- `lexer` **Lexer** -- `token` **(Integer | [String](#string))** -- `extractDoc` **[Boolean](#boolean)** -- `debug` **[Boolean](#boolean)** - -## getTokenName - -helper : gets a token name - -**Parameters** - -- `token` - -## parse - -main entry point : converts a source code to AST - -**Parameters** - -- `code` - -## raiseError - -Raise an error - -**Parameters** - -- `message` -- `msgExpect` -- `expect` -- `token` - -## error - -handling errors - -**Parameters** - -- `expect` - -## node - -Creates a new AST node - -**Parameters** - -- `name` - -## expectEndOfStatement - -expects an end of statement or end of file - -## expect - -Force the parser to check the current token. - -If the current token does not match to expected token, -the an error will be raised. - -If the suppressError mode is activated, then the error will -be added to the program error stack and this function will return `false`. - -**Parameters** - -- `token` **([String](#string) \| [Number](#number))** - - -- Throws **any** Error - -Returns **(Parser | False)** - -## text - -Returns the current token contents - -Returns **[String](#string)** - -## next - -consume the next token \* - -## ignoreComments - -consume comments (if found) \* - -## nextWithComments - -consume the next token (including doc) \* - -## is - -Check if token is of specified type - -**Parameters** - -- `type` - -## read_token - -convert an token to ast \* - -## read_list - -Helper : reads a list of tokens / sample : T_STRING ',' T_STRING ... - -```ebnf -list ::= separator? ( item separator )* item -``` - -**Parameters** - -- `item` -- `separator` -- `preserveFirstSeparator` - -# ignoreStack - -outputs some debug information on current token \* - -# read_array - -Parse an array - -```ebnf -array ::= T_ARRAY '(' array_pair_list ')' | - '[' array_pair_list ']' -``` - -# read_array_pair_list - -Reads an array entry item - -```ebnf -array_pair_list ::= '&' w_variable | - ( - expr ( - T_DOUBLE_ARROW ( - expr | '&' w_variable - ) - )? - ) -``` - -# read_dim_offset - -```ebnf - dim_offset ::= expr? -``` - -# read_class - -reading a class - -```ebnf -class ::= class_scope? T_CLASS T_STRING (T_EXTENDS NAMESPACE_NAME)? (T_IMPLEMENTS (NAMESPACE_NAME ',')* NAMESPACE_NAME)? '{' CLASS_BODY '}' -``` - -# read_class_scope - -Read the class visibility - -```ebnf - class_scope ::= (T_FINAL | T_ABSTRACT)? -``` - -# read_class_body - -Reads a class body - -```ebnf - class_body ::= (member_flags? (T_VAR | T_STRING | T_FUNCTION))* -``` - -# read_variable_list - -Reads variable list - -```ebnf - variable_list ::= (variable_declaration ',')* variable_declaration -``` - -# read_constant_list - -Reads constant list - -```ebnf - constant_list ::= T_CONST (constant_declaration ',')* constant_declaration -``` - -# read_member_flags - -Read member flags - -Returns **any** array - 1st index : 0 => public, 1 => protected, 2 => private - 2nd index : 0 => instance member, 1 => static member - 3rd index : 0 => normal, 1 => abstract member, 2 => final member - -# read_interface - -reading an interface - -```ebnf -interface ::= class_scope? T_INTERFACE T_STRING (T_EXTENDS (NAMESPACE_NAME ',')* NAMESPACE_NAME)? '{' INTERFACE_BODY '}' -``` - -# read_interface_body - -Reads an interface body - -```ebnf - interface_body ::= (member_flags? (T_CONST | T_FUNCTION))* -``` - -# read_trait - -reading a trait - -```ebnf -trait ::= T_TRAIT T_STRING (T_EXTENDS (NAMESPACE_NAME ',')* NAMESPACE_NAME)? '{' FUNCTION* '}' -``` - -# read_trait_use_statement - -reading a use statement - -```ebnf -trait_use_statement ::= namespace_name (',' namespace_name)* ('{' trait_use_alias '}')? -``` - -# read_trait_use_alias - -Reading trait alias - -```ebnf -trait_use_alias ::= namespace_name ( T_DOUBLE_COLON T_STRING )? (T_INSTEADOF namespace_name) | (T_AS member_flags? T_STRING) -``` - -# read_variable_declaration - -Reads a variable declaration - -```ebnf - variable_declaration ::= T_VARIABLE '=' scalar -``` - -# read_constant_declaration - -Reads a constant declaration - -```ebnf - constant_declaration ::= T_STRING '=' expr -``` - -Returns **[Constant](#constant)** [:link:](AST.md#constant) - -# read_expr_item - -```ebnf -Reads an expression - expr ::= @todo -``` - -# read_new_expr - -```ebnf - new_expr ::= T_NEW (namespace_name function_argument_list) | (T_CLASS ... class declaration) -``` - - - -# read_class_name_reference - -Reads a class name - -```ebnf -class_name_reference ::= namespace_name | variable -``` - -# read_assignment_list - -```ebnf - assignment_list ::= assignment_list_element (',' assignment_list_element?)* -``` - -# read_assignment_list_element - -```ebnf - assignment_list_element ::= expr | expr T_DOUBLE_ARROW expr -``` - -# is_reference - -checks if current token is a reference keyword - -# is_variadic - -checks if current token is a variadic keyword - -# read_function - -reading a function - -```ebnf -function ::= function_declaration code_block -``` - -# read_function_declaration - -reads a function declaration (without his body) - -```ebnf -function_declaration ::= T_FUNCTION '&'? T_STRING '(' parameter_list ')' -``` - -# read_lexical_var - -```ebnf -lexical_var ::= '&'? T_VARIABLE -``` - -# read_parameter_list - -reads a list of parameters - -```ebnf - parameter_list ::= (parameter ',')* parameter? -``` - -# read_parameter - -```ebnf - parameter ::= type? '&'? T_ELLIPSIS? T_VARIABLE ('=' expr)? -``` - -# read_function_argument_list - -```ebnf - function_argument_list ::= '(' (argument_list (',' argument_list)*)? ')' -``` - -# read_argument_list - -```ebnf - argument_list ::= T_ELLIPSIS? expr -``` - -# read_type - -read type hinting - -```ebnf - type ::= T_ARRAY | T_CALLABLE | namespace_name -``` - -# read_if - -```ebnf - if ::= '(' expr ')' ':' ... -``` - -# read_if_expr - -reads an if expression : '(' expr ')' - -# read_elseif_short - -reads an elseif (expr): statements - -# read_else_short - -# read_short_form - -Reads a short form of tokens - -# read_while - -Reads a while statement - -# read_foreach - -```ebnf -foreach ::= '(' expr T_AS foreach_variable (T_DOUBLE_ARROW foreach_variable)? ')' statement -``` - -# read_foreach_variable - -```ebnf -foreach_variable = ('&'? variable) | (T_LIST '(' assignment_list ')') -``` - -# read_start - -```ebnf -start ::= (namespace | top_statement)* -``` - -# read_namespace - -```ebnf -namespace ::= T_NAMESPACE namespace_name? '{' - top_statements -'}' -| T_NAMESPACE namespace_name ';' top_statements -``` - -# read_namespace_name - -reading a namespace name - -```ebnf - namespace_name ::= T_NS_SEPARATOR? (T_STRING T_NS_SEPARATOR)* T_STRING -``` - -# read_use_statements - -```ebnf -use_statements ::= - use_statements ',' use_statement - | use_statement -``` - -# read_inline_use_declaration - -```ebnf - inline_use_declaration ::= ... -``` - -# read_use_statement_mixed - -```ebnf - use_statement_mixed ::= - use_statement (T_AS T_STRING | '{' read_inline_use_declaration '}' ) - (',' read_use_statement)* -``` - -# read_use_statement - -```ebnf -use_statement ::= ( - (T_FUNCTION | T_CONST)? namespace_name - ) -``` - -# resolve_special_chars - -Unescape special chars - -# read_scalar - -```ebnf - scalar ::= T_MAGIC_CONST - | T_LNUMBER | T_DNUMBER - | T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE? T_END_HEREDOC - | '"' encaps_list '"' - | T_START_HEREDOC encaps_list T_END_HEREDOC - | namespace_name (T_DOUBLE_COLON T_STRING)? -``` - -# read_dereferencable - -Handles the dereferencing - -# read_encapsed_string_item - -```ebnf -encapsed_string_item ::= T_ENCAPSED_AND_WHITESPACE - | T_DOLLAR_OPEN_CURLY_BRACES expr '}' - | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '}' - | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}' - | variable - | T_CURLY_OPEN variable '}' -``` - -# read_encapsed_string - -Reads an encapsed string - -# get_magic_constant - -Constant token - -# read_top_statements - -reading a list of top statements (helper for top_statement\*) - -```ebnf - top_statements ::= top_statement* -``` - -# read_top_statement - -reading a top statement - -```ebnf - top_statement ::= - namespace | function | class - | interface | trait - | use_statements | const_list - | statement -``` - -# read_inner_statements - -reads a list of simple inner statements (helper for inner_statement\*) - -```ebnf - inner_statements ::= inner_statement* -``` - -# read_const_list - -Reads a list of constants declaration - -```ebnf - const_list ::= T_CONST T_STRING '=' expr (',' T_STRING '=' expr)* ';' -``` - -# read_declare_list - -Reads a list of constants declaration - -```ebnf - const_list ::= T_CONST T_STRING '=' expr (',' T_STRING '=' expr)* -``` - -# read_inner_statement - -reads a simple inner statement - -```ebnf - inner_statement ::= '{' inner_statements '}' | token -``` - -# read_statement - -Reads statements - -# read_code_block - -```ebnf - code_block ::= '{' (inner_statements | top_statements) '}' -``` - -# read_switch - -Reads a switch statement - -```ebnf - switch ::= T_SWITCH '(' expr ')' switch_case_list -``` - -# read_switch_case_list - -```ebnf - switch_case_list ::= '{' ';'? case_list* '}' | ':' ';'? case_list* T_ENDSWITCH ';' -``` - -# read_case_list - -```ebnf - case_list ::= ((T_CASE expr) | T_DEFAULT) (':' | ';') inner_statement* -``` - -# read_try - -```ebnf - try ::= T_TRY '{' inner_statement* '}' - ( - T_CATCH '(' namespace_name variable ')' '{' inner_statement* '}' - )* - (T_FINALLY '{' inner_statement* '}')? -``` - -# read_comment - -Comments with // or # - -# read_doc_comment - -Comments with / \*\* \*\* / - -# read_variable - -Reads a variable - -```ebnf - variable ::= ...complex @todo -``` - -Some samples of parsed code : - -```php - $var // simple var - classname::CONST_NAME // dynamic class name with const retrieval - foo() // function call - $var->func()->property // chained calls -``` - -# read_encaps_var_offset - - - -# read_reference_variable - -```ebnf - reference_variable ::= simple_variable ('[' OFFSET ']')* | '{' EXPR '}' -``` - - - $foo[123]; // foo is an array ==> gets its entry - $foo{1}; // foo is a string ==> get the 2nd char offset - ${'foo'}[123]; // get the dynamic var $foo - $foo[123]{1}; // gets the 2nd char from the 123 array entry - - -# read_simple_variable - -```ebnf - simple_variable ::= T_VARIABLE | '$' '{' expr '}' | '$' simple_variable -``` - -# AST - -## Class hierarchy - -- [Node](#Node) - - [Expression](#expression) - - [Literal](#literal) - - [Boolean](#boolean) - - [String](#string) - - [Number](#number) - - [Inline](#inline) - - [Magic](#magic) - - [Shell](#shell) - - [Array](#array) - - [Variable](#variable) - - [Statement](#statement) - - [Block](#block) - - [Program](#program) - - [Namespace](#namespace) - - [Sys](#sys) - - [Echo](#echo) - - [Print](#print) - - [Isset](#isset) - - [Unset](#unset) - - [Empty](#empty) - - [Declaration](#declaration) - - [Class](#class) - - [Constant](#constant) - - [ClassConstant](#classconstant) - - [Function](#function) - - [Method](#method) - - [Parameter](#parameter) - - [Property](#property) - - [Eval](#eval) - - [Exit](#exit) - - [Clone](#clone) - - [Coalesce](#coalesce) - - [Include](#include) - - [Assign](#assign) - - [Identifier](#identifier) - - [Entry](#entry) - - [Documentation](#documentation) - - [Error](#error) -- [Location](#location) -- [Position](#position) - -* * * - -**Parameters** - -- `withPositions` -- `withSource` - -## prepare - -Prepares an AST node - -**Parameters** - -- `kind` **([String](#string) | null)** Defines the node type - (if null, the kind must be passed at the function call) -- `parser` **Parser** The parser instance (use for extracting locations) - -Returns **[Function](#function)** - -# AST - -The AST builder class - -**Parameters** - -- `withPositions` -- `withSource` - -**Properties** - -- `withPositions` **[Boolean](#boolean)** Should locate any node (by default false) -- `withSource` **[Boolean](#boolean)** Should extract the node original code (by default false) - -## prepare - -Prepares an AST node - -**Parameters** - -- `kind` **([String](#string) | null)** Defines the node type - (if null, the kind must be passed at the function call) -- `parser` **Parser** The parser instance (use for extracting locations) - -Returns **[Function](#function)** - -# Location - -Defines the location of the node (with it's source contents as string) - -**Parameters** - -- `source` -- `start` -- `end` - -**Properties** - -- `source` **([String](#string) | null)** -- `start` **[Position](#position)** -- `end` **[Position](#position)** - -# Position - -Each Position object consists of a line number (1-indexed) and a column number (0-indexed): - -**Parameters** - -- `line` -- `column` -- `offset` - -**Properties** - -- `line` **[Number](#number)** -- `column` **[Number](#number)** -- `offset` **[Number](#number)** - -# Array - -**Extends Expression** - -Defines an array structure - -**Properties** - -- `items` **[Array](#array)<[Entry](#entry)>** -- `shortForm` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** - -# Expression - -**Extends Node** - -Any expression node. Since the left-hand side of an assignment may -be any expression in general, an expression can also be a pattern. - -# Assign - -**Extends Statement** - -Assigns a value to the specified target - -**Properties** - -- `left` **[Expression](#expression)** -- `right` **[Expression](#expression)** -- `operator` **[String](#string)** - -# Statement - -**Extends Node** - -Any statement. - -# Boolean - -**Extends Literal** - -Defines a boolean value (true/false) - -# Class - -**Extends Declaration** - -A class definition - -**Properties** - -- `extends` **([Identifier](#identifier) | null)** -- `implements` **[Array](#array)<[Identifier](#identifier)>** -- `body` **[Array](#array)<[Declaration](#declaration)>** -- `isAnonymous` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** -- `isAbstract` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** -- `isFinal` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** -- `isFinal` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** - -# Declaration - -**Extends Statement** - -A declaration statement (function, class, interface...) - -**Properties** - -- `name` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** - -## parseFlags - -Generic flags parser - -**Parameters** - -- `flags` **[Array](#array)<Integer>** - -Returns **void** - -# ClassConstant - -**Extends Constant** - -Defines a class/interface/trait constant - -**Properties** - -- `isStatic` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** -- `visibility` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** - -# Clone - -**Extends Statement** - -Defines a clone call - -**Properties** - -- `what` **[Expression](#expression)** - -# Coalesce - -**Extends Statement** - -Verify is the test property is defined and is not null, and returns -is, otherwise returns the ifnull expression. - -**Properties** - -- `test` **[Expression](#expression)** The expression to be testes -- `ifnull` **[Expression](#expression)** The returned expression if test is null - -# Constant - -**Extends Declaration** - -Defines a namespace constant - -**Properties** - -- `value` **([Node](#node) | null)** - -# Echo - -**Extends Sys** - -Defines system based call - -# Sys - -**Extends Statement** - -Defines system based call - -**Properties** - -- `arguments` **[Array](#array)<[Node](#node)>** - -# Empty - -**Extends Sys** - -Defines an empty check call - -# Entry - -**Extends Node** - -An array entry - -**Properties** - -- `key` **([Node](#node) | null)** -- `value` **[Node](#node)** - -# Node - -A generic AST node - -**Parameters** - -- `kind` -- `location` - -**Properties** - -- `loc` **([Location](#location) | null)** -- `kind` **[String](#string)** - -## extends - -Helper for extending the Node class - -**Parameters** - -- `constructor` **[Function](#function)** - -Returns **[Function](#function)** - -# Error - -**Extends Node** - -Defines an error node (used only on silentMode) - -**Properties** - -- `message` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** -- `line` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** -- `token` **([number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number) \| [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String))** -- `expected` **([string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array))** - -# Eval - -**Extends Statement** - -Defines an eval statement - -**Properties** - -- `source` **[Node](#node)** - -# Exit - -**Extends Statement** - -Defines an exit / die call - -**Properties** - -- `status` **([Node](#node) | null)** - -# Function - -**Extends Declaration** - -Defines a classic function - -**Properties** - -- `arguments` **[Array](#array)<Argument>** -- `type` **[Identifier](#identifier)** -- `byref` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** -- `children` **[Array](#array)<[Node](#node)>** - -# Identifier - -**Extends Node** - -Defines an identifier node - -**Properties** - -- `name` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** -- `fqn` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** - -# Include - -**Extends Statement** - -Defines system include call - -**Properties** - -- `target` **[Node](#node)** -- `once` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** -- `require` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** - -# Inline - -**Extends Literal** - -Defines inline html output (treated as echo output) - -# Isset - -**Extends Sys** - -Defines an isset call - -# ArrayExpression - -**Extends Expression** - -Defines an array structure - -**Properties** - -- `value` **([Node](#node) \| [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) \| [number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number) \| [boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean) | null)** - -# Magic - -**Extends Literal** - -Defines magic constant - -# Method - -**Extends Function** - -Defines a class/interface/trait method - -**Properties** - -- `isAbstract` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** -- `isFinal` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** -- `isStatic` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** -- `visibility` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** - -# Namespace - -**Extends Block** - -The main program node - -**Properties** - -- `name` **[Identifier](#identifier)** -- `withBrackets` **[Boolean](#boolean)** - -# Block - -**Extends Statement** - -A block statement, i.e., a sequence of statements surrounded by braces. - -**Properties** - -- `children` **[Array](#array)<[Node](#node)>** - -# Number - -**Extends Literal** - -Defines a numeric value - -# Parameter - -**Extends Declaration** - -Defines a function parameter - -**Properties** - -- `type` **([Identifier](#identifier) | null)** -- `value` **([Node](#node) | null)** -- `byref` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** -- `variadic` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** - -# Print - -**Extends Sys** - -Outputs - -# Program - -**Extends Block** - -The main program node - -**Properties** - -- `errors` **[Array](#array)<[Error](#error)>** - -# Property - -**Extends Declaration** - -Defines a class property - -**Properties** - -- `isFinal` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** -- `isStatic` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** -- `visibility` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** -- `value` **([Node](#node) | null)** - -# Shell - -**Extends Literal** - -Defines inline html output (treated as echo output) - -# String - -**Extends Literal** - -Defines inline html output (treated as echo output) - -**Properties** - -- `isDoubleQuote` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** - -# Unset - -**Extends Sys** - -Deletes references to a list of variables - -# Variable - -**Extends Expression** - -Any expression node. Since the left-hand side of an assignment may -be any expression in general, an expression can also be a pattern. - -**Properties** - -- `identifier` **([String](#string) \| [Node](#node))** -- `byref` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** diff --git a/docs/parser.md b/docs/parser.md index eeab64eb3..f0eee7a18 100644 --- a/docs/parser.md +++ b/docs/parser.md @@ -64,6 +64,8 @@ Creates a new AST node expects an end of statement or end of file +Returns **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** + ## expect Force the parser to check the current token. @@ -81,7 +83,7 @@ be added to the program error stack and this function will return `false`. - Throws **any** Error -Returns **(Parser | False)** +Returns **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** ## text @@ -113,20 +115,6 @@ Check if token is of specified type convert an token to ast \* -## read_list - -Helper : reads a list of tokens / sample : T_STRING ',' T_STRING ... - -```ebnf -list ::= separator? ( item separator )* item -``` - -**Parameters** - -- `item` -- `separator` -- `preserveFirstSeparator` - # ignoreStack outputs some debug information on current token \* @@ -215,7 +203,7 @@ Returns **any** array reading an interface ```ebnf -interface ::= class_scope? T_INTERFACE T_STRING (T_EXTENDS (NAMESPACE_NAME ',')* NAMESPACE_NAME)? '{' INTERFACE_BODY '}' +interface ::= T_INTERFACE T_STRING (T_EXTENDS (NAMESPACE_NAME ',')* NAMESPACE_NAME)? '{' INTERFACE_BODY '}' ``` # read_interface_body @@ -270,11 +258,11 @@ Returns **Constant** [:link:](AST.md#constant) # read_comment -Comments with // or # +Comments with // or # or / _ ... _ / # read_doc_comment -Comments with / \*\* \*\* / +Comments with / \*_ ... _ / # read_expr_item @@ -357,6 +345,8 @@ reads a list of parameters # read_function_argument_list +Reads a list of arguments + ```ebnf function_argument_list ::= '(' (argument_list (',' argument_list)*)? ')' ``` @@ -377,6 +367,8 @@ read type hinting # read_if +Reads an IF statement + ```ebnf if ::= '(' expr ')' ':' ... ``` @@ -391,26 +383,60 @@ reads an elseif (expr): statements # read_else_short -# read_short_form - -Reads a short form of tokens - # read_while Reads a while statement +```ebnf +while ::= T_WHILE (statement | ':' inner_statement_list T_ENDWHILE ';') +``` + +Returns **While** + +# read_do + +Reads a do / while loop + +```ebnf +do ::= T_DO statement T_WHILE '(' expr ')' ';' +``` + +Returns **Do** + +# read_for + +Read a for incremental loop + +```ebnf +for ::= T_FOR '(' for_exprs ';' for_exprs ';' for_exprs ')' for_statement +for_statement ::= statement | ':' inner_statement_list T_ENDFOR ';' +for_exprs ::= expr? (',' expr)* +``` + +Returns **For** + # read_foreach +Reads a foreach loop + ```ebnf foreach ::= '(' expr T_AS foreach_variable (T_DOUBLE_ARROW foreach_variable)? ')' statement ``` +Returns **Foreach** + # read_foreach_variable +Reads a foreach variable statement + ```ebnf -foreach_variable = ('&'? variable) | (T_LIST '(' assignment_list ')') +foreach_variable = variable | + T_LIST '(' assignment_list ')' | + '[' array_pair_list ']' ``` +Returns **Expression** + # read_start ```ebnf @@ -419,6 +445,8 @@ start ::= (namespace | top_statement)* # read_namespace +Reads a namespace declaration block + ```ebnf namespace ::= T_NAMESPACE namespace_name? '{' top_statements @@ -426,44 +454,72 @@ namespace ::= T_NAMESPACE namespace_name? '{' | T_NAMESPACE namespace_name ';' top_statements ``` +Returns **Namespace** + # read_namespace_name -reading a namespace name +Reads a namespace name ```ebnf namespace_name ::= T_NS_SEPARATOR? (T_STRING T_NS_SEPARATOR)* T_STRING ``` -# read_use_statements +Returns **Identifier** + +# read_use_statement + +Reads a use statement + +```ebnf +use_statement ::= T_USE + use_type? use_declarations | + use_type use_statement '{' use_declarations '}' | + use_statement '{' use_declarations(=>typed) '}' +';' +``` + +Returns **UseGroup** + +# read_use_declaration + +Reads a use declaration ```ebnf -use_statements ::= - use_statements ',' use_statement - | use_statement +use_declaration ::= use_type? namespace_name use_alias ``` -# read_inline_use_declaration +Returns **UseItem** + +# read_use_declarations + +Reads a list of use declarations ```ebnf - inline_use_declaration ::= ... +use_declarations ::= use_declaration (',' use_declaration)* ``` -# read_use_statement_mixed +Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)<UseItem>** + +# read_use_alias + +Reads a use statement ```ebnf - use_statement_mixed ::= - use_statement (T_AS T_STRING | '{' read_inline_use_declaration '}' ) - (',' read_use_statement)* +use_alias ::= (T_AS T_STRING)? ``` -# read_use_statement +Returns **([String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) | null)** + +# read_use_type + +Reads the namespace type declaration ```ebnf -use_statement ::= ( - (T_FUNCTION | T_CONST)? namespace_name - ) +use_type ::= (T_FUNCTION | T_CONST)? ``` +Returns **([String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) | null)** Possible values : function, const + # resolve_special_chars Unescape special chars @@ -572,6 +628,8 @@ Reads a switch statement switch ::= T_SWITCH '(' expr ')' switch_case_list ``` +Returns **Switch** + # read_switch_case_list ```ebnf @@ -594,17 +652,54 @@ Reads a switch statement (T_FINALLY '{' inner_statement* '}')? ``` +Returns **Try** + +# read_short_form + +Reads a short form of tokens + +**Parameters** + +- `token` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** The ending token + +Returns **Block** + +# read_list + +Helper : reads a list of tokens / sample : T_STRING ',' T_STRING ... + +```ebnf +list ::= separator? ( item separator )* item +``` + +# read_name_list + +Reads a list of names separated by a comma + +```ebnf +name_list ::= namespace (',' namespace)* +``` + +Sample code : + +```php +** + # read_variable Reads a variable ```ebnf - variable ::= ...complex @todo + variable ::= &? ...complex @todo ``` Some samples of parsed code : ```php + &$var // simple var $var // simple var classname::CONST_NAME // dynamic class name with const retrieval foo() // function call diff --git a/gruntfile.js b/gruntfile.js index dfe3b898c..0477b5e24 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -63,7 +63,7 @@ module.exports = function(grunt) { version: "<%= pkg.version %>", name: "<%= pkg.name %>", filename: "README.md", - shallow: false + shallow: true }, files: [{ src: ['src/index.js'] diff --git a/package.json b/package.json index dbcf39492..0f932c123 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,8 @@ "description": "Parse PHP code with NodeJS and convert it to AST", "main": "src/index.js", "scripts": { - "bench": "node --expose-gc bin/bench.js", - "test": "node --stack-size=5000 bin/test.js -r -d test/", - "cover": "node --stack-size=5000 node_modules/istanbul/lib/cli.js cover -x \"**/bin/**\" bin/test.js -- -m test/functional/", - "mocha": "node node_modules/mocha/bin/mocha test/functional --stack-size=5000" + "test": "node node_modules/mocha/bin/mocha test --stack-size=5000", + "cover": "node --stack-size=5000 node_modules/istanbul/lib/cli.js cover node_modules/mocha/bin/_mocha" }, "repository": { "type": "git", @@ -30,7 +28,6 @@ "grunt-contrib-uglify": "^2.0.0", "grunt-documentation": "^1.2.1", "istanbul": "0.3.x", - "memwatch-next": "^0.3.0", "mocha": "^2.0.1", "should": "^8.3.0" } diff --git a/src/ast.js b/src/ast.js index 478adb33d..dacef3f35 100644 --- a/src/ast.js +++ b/src/ast.js @@ -1,7 +1,7 @@ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors - * @url http://glayzzle.com + * @url http://gla*yzzle.com */ var Location = require('./ast/location'); @@ -10,8 +10,34 @@ var Position = require('./ast/position'); /** * ## Class hierarchy * + * - [Location](#location) + * - [Position](#position) * - [Node](#Node) + * - [Identifier](#identifier) + * - [TraitUse](#traituse) + * - [TraitAlias](#traitalias) + * - [TraitPrecedence](#traitprecedence) + * - [Entry](#entry) + * - [Case](#case) + * - [Label](#label) + * - [Doc](#doc) + * - [Error](#error) * - [Expression](#expression) + * - [Array](#array) + * - [Variable](#variable) + * - [ConstRef](#constref) + * - [Lookup](#lookup) + * - [PropertyLookup](#propertylookup) + * - [StaticLookup](#staticlookup) + * - [OffsetLookup](#offsetlookup) + * - [Operation](#operation) + * - [Coalesce](#coalesce) + * - [Pre](#pre) + * - [Post](#post) + * - [Bin](#bin) + * - [Bool](#Bool) + * - [Unary](#unary) + * - [Cast](#cast) * - [Literal](#literal) * - [Boolean](#boolean) * - [String](#string) @@ -19,38 +45,49 @@ var Position = require('./ast/position'); * - [Inline](#inline) * - [Magic](#magic) * - [Shell](#shell) - * - [Array](#array) - * - [Variable](#variable) * - [Statement](#statement) + * - [Eval](#eval) + * - [Exit](#exit) + * - [Clone](#clone) + * - [Global](#global) + * - [Include](#include) + * - [Assign](#assign) + * - [RetIf](#retif) + * - [If](#if) + * - [Do](#do) + * - [While](#while) + * - [For](#for) + * - [Foreach](#foreach) + * - [Switch](#switch) + * - [Goto](#goto) + * - [Silent](#silent) + * - [Try](#try) + * - [Catch](#catch) + * - [Call](#call) + * - [Closure](#closure) + * - [New](#new) + * - [UseGroup](#usegroup) + * - [UseItem](#useitem) * - [Block](#block) * - [Program](#program) * - [Namespace](#namespace) * - [Sys](#sys) * - [Echo](#echo) + * - [List](#list) * - [Print](#print) * - [Isset](#isset) * - [Unset](#unset) * - [Empty](#empty) * - [Declaration](#declaration) * - [Class](#class) + * - [Interface](#interface) + * - [Trait](#trait) * - [Constant](#constant) * - [ClassConstant](#classconstant) * - [Function](#function) * - [Method](#method) * - [Parameter](#parameter) * - [Property](#property) - * - [Eval](#eval) - * - [Exit](#exit) - * - [Clone](#clone) - * - [Coalesce](#coalesce) - * - [Include](#include) - * - [Assign](#assign) - * - [Identifier](#identifier) - * - [Entry](#entry) - * - [Documentation](#documentation) - * - [Error](#error) - * - [Location](#location) - * - [Position](#position) * --- */ @@ -65,6 +102,20 @@ var AST = function(withPositions, withSource) { this.withSource = withSource; }; +/** + * Create a position node from specified parser + * including it's lexer current state + * @param {Parser} + * @return {Position} + */ +AST.prototype.position = function(parser) { + return new Position( + parser.lexer.yylloc.first_line, + parser.lexer.yylloc.first_column, + parser.lexer.yylloc.first_offset + ); +}; + /** * Prepares an AST node * @param {String|null} kind - Defines the node type @@ -75,11 +126,7 @@ var AST = function(withPositions, withSource) { AST.prototype.prepare = function(kind, parser) { var start = null; if (this.withPositions || this.withSource) { - start = new Position( - parser.lexer.yylloc.first_line, - parser.lexer.yylloc.first_column, - parser.lexer.yylloc.first_offset - ); + start = this.position(parser); } var self = this; // returns the node @@ -91,14 +138,14 @@ AST.prototype.prepare = function(kind, parser) { if (self.withSource) { src = parser.lexer._input.substring( start.offset, - parser.lexer.offset + parser.lexer.yylloc.prev_offset ); } if (self.withPositions) { location = new Location(src, start, new Position( - parser.lexer.yylloc.first_line, - parser.lexer.yylloc.first_column, - parser.lexer.offset + parser.lexer.yylloc.prev_line, + parser.lexer.yylloc.prev_column, + parser.lexer.yylloc.prev_offset )); } else { location = new Location(src, null, null); @@ -125,36 +172,76 @@ AST.prototype.prepare = function(kind, parser) { [ require('./ast/array'), require('./ast/assign'), + require('./ast/bin'), + require('./ast/block'), + require('./ast/bool'), require('./ast/boolean'), + require('./ast/break'), + require('./ast/call'), + require('./ast/case'), + require('./ast/cast'), + require('./ast/catch'), require('./ast/class'), require('./ast/classconstant'), require('./ast/clone'), + require('./ast/closure'), require('./ast/coalesce'), require('./ast/constant'), + require('./ast/constref'), + require('./ast/continue'), + require('./ast/do'), + require('./ast/doc'), require('./ast/echo'), require('./ast/empty'), require('./ast/entry'), require('./ast/error'), require('./ast/eval'), require('./ast/exit'), + require('./ast/for'), + require('./ast/foreach'), require('./ast/function'), + require('./ast/global'), + require('./ast/goto'), require('./ast/identifier'), + require('./ast/if'), require('./ast/include'), require('./ast/inline'), + require('./ast/interface'), require('./ast/isset'), + require('./ast/label'), + require('./ast/list'), require('./ast/literal'), require('./ast/magic'), require('./ast/method'), require('./ast/namespace'), + require('./ast/new'), require('./ast/number'), + require('./ast/offsetlookup'), require('./ast/parameter'), + require('./ast/post'), + require('./ast/pre'), require('./ast/print'), require('./ast/program'), require('./ast/property'), + require('./ast/propertylookup'), + require('./ast/retif'), + require('./ast/return'), require('./ast/shell'), + require('./ast/silent'), + require('./ast/staticlookup'), require('./ast/string'), + require('./ast/switch'), + require('./ast/trait'), + require('./ast/traitalias'), + require('./ast/traitprecedence'), + require('./ast/traituse'), + require('./ast/try'), + require('./ast/unary'), require('./ast/unset'), - require('./ast/variable') + require('./ast/usegroup'), + require('./ast/useitem'), + require('./ast/variable'), + require('./ast/while') ].forEach(function (ctor) { var kind = ctor.prototype.constructor.name.toLowerCase(); if (kind[0] === '_') kind = kind.substring(1); diff --git a/src/ast/bin.js b/src/ast/bin.js new file mode 100644 index 000000000..0ff83bfcf --- /dev/null +++ b/src/ast/bin.js @@ -0,0 +1,26 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +var Operation = require('./operation'); +var KIND = 'bin'; + +/** + * Binary operations + * @constructor Bin + * @extends {Operation} + * @property {String} type + * @property {Expression} left + * @property {Expression} right + */ +var Bin = Operation.extends(function Bin(type, left, right, location) { + Operation.apply(this, [KIND, location]); + this.type = type; + this.left = left; + this.right = right; +}); + +module.exports = Bin; diff --git a/src/ast/bool.js b/src/ast/bool.js new file mode 100644 index 000000000..badfc6624 --- /dev/null +++ b/src/ast/bool.js @@ -0,0 +1,26 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +var Operation = require('./operation'); +var KIND = 'bool'; + +/** + * Boolean operations + * @constructor Bool + * @extends {Operation} + * @property {String} type + * @property {Expression} left + * @property {Expression} right + */ +var Bool = Operation.extends(function Bool(type, left, right, location) { + Operation.apply(this, [KIND, location]); + this.type = type; + this.left = left; + this.right = right; +}); + +module.exports = Bool; diff --git a/src/ast/break.js b/src/ast/break.js new file mode 100644 index 000000000..47a4dd5ba --- /dev/null +++ b/src/ast/break.js @@ -0,0 +1,19 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; +var Node = require('./node'); +var KIND = 'break'; + +/** + * A break statement + * @constructor Break + * @extends {Node} + */ +var Break = Node.extends(function Break(location) { + Node.apply(this, [KIND, location]); +}); + +module.exports = Break; diff --git a/src/ast/call.js b/src/ast/call.js new file mode 100644 index 000000000..6e44333f7 --- /dev/null +++ b/src/ast/call.js @@ -0,0 +1,24 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +var Statement = require('./statement'); +var KIND = 'call'; + +/** + * Executes a call statement + * @constructor Call + * @extends {Statement} + * @property {Identifier|Variable|??} what + * @property {Arguments[]} arguments + */ +var Call = Statement.extends(function Call(what, args, location) { + Statement.apply(this, [KIND, location]); + this.what = what; + this.arguments = args; +}); + +module.exports = Call; diff --git a/src/ast/case.js b/src/ast/case.js new file mode 100644 index 000000000..126be6728 --- /dev/null +++ b/src/ast/case.js @@ -0,0 +1,23 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; +var Node = require('./node'); +var KIND = 'case'; + +/** + * A switch case statement + * @constructor Case + * @extends {Node} + * @property {Expression|null} test - if null, means that the default case + * @property {Block|null} body + */ +var Case = Node.extends(function Case(test, body, location) { + Node.apply(this, [KIND, location]); + this.test = test; + this.body = body; +}); + +module.exports = Case; diff --git a/src/ast/cast.js b/src/ast/cast.js new file mode 100644 index 000000000..0b7b2a0f1 --- /dev/null +++ b/src/ast/cast.js @@ -0,0 +1,24 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +var Operation = require('./operation'); +var KIND = 'cast'; + +/** + * Binary operations + * @constructor Cast + * @extends {Operation} + * @property {String} type + * @property {Expression} what + */ +var Cast = Operation.extends(function Cast(type, what, location) { + Operation.apply(this, [KIND, location]); + this.type = type; + this.what = what; +}); + +module.exports = Cast; diff --git a/src/ast/catch.js b/src/ast/catch.js new file mode 100644 index 000000000..a6e1cda1c --- /dev/null +++ b/src/ast/catch.js @@ -0,0 +1,27 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +var Statement = require('./statement'); +var KIND = 'catch'; + +/** + * Defines a catch statement + * @constructor Try + * @extends {Statement} + * @property {Identifier[]} what + * @property {Variable} variable + * @property {Statement} body + * @see http://php.net/manual/en/language.exceptions.php + */ +var Catch = Statement.extends(function Catch(body, what, variable, location) { + Statement.apply(this, [KIND, location]); + this.body = body; + this.what = what; + this.variable = variable; +}); + +module.exports = Catch; diff --git a/src/ast/class.js b/src/ast/class.js index 5c2a511b9..13b7aeab7 100644 --- a/src/ast/class.js +++ b/src/ast/class.js @@ -18,7 +18,6 @@ var KIND = 'class'; * @property {boolean} isAnonymous * @property {boolean} isAbstract * @property {boolean} isFinal - * @property {boolean} isFinal */ var Class = Declaration.extends(function Class(name, ext, impl, body, flags, location) { Declaration.apply(this, [KIND, name, location]); diff --git a/src/ast/closure.js b/src/ast/closure.js new file mode 100644 index 000000000..2e5ea9364 --- /dev/null +++ b/src/ast/closure.js @@ -0,0 +1,29 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; +var Statement = require('./statement'); +var KIND = 'closure'; + +/** + * Defines a closure + * @constructor Closure + * @extends {Statement} + * @property {Parameter[]} arguments + * @property {Identifier} type + * @property {boolean} byref + * @property {boolean} nullable + * @property {Block|null} body + */ +var Closure = Statement.extends(function Closure(args, byref, type, nullable, location) { + Statement.apply(this, [KIND, location]); + this.arguments = args; + this.byref = byref; + this.type = type; + this.nullable = nullable; + this.body = null; +}); + +module.exports = Closure; diff --git a/src/ast/coalesce.js b/src/ast/coalesce.js index f965a851e..6561dddbd 100644 --- a/src/ast/coalesce.js +++ b/src/ast/coalesce.js @@ -4,20 +4,20 @@ * @url http://glayzzle.com */ -var Statement = require('./statement'); +var Operation = require('./operation'); var KIND = 'coalesce'; /** * Verify is the test property is defined and is not null, and returns * is, otherwise returns the ifnull expression. * @constructor Coalesce - * @extends {Statement} + * @extends {Operation} * @property {Expression} test - The expression to be testes * @property {Expression} ifnull - The returned expression if test is null * @see https://wiki.php.net/rfc/isset_ternary */ -var Coalesce = Statement.extends(function Coalesce(test, ifnull, location) { - Statement.apply(this, [KIND, location]); +var Coalesce = Operation.extends(function Coalesce(test, ifnull, location) { + Operation.apply(this, [KIND, location]); this.test = test; this.ifnull = ifnull; }); diff --git a/src/ast/constref.js b/src/ast/constref.js new file mode 100644 index 000000000..f97930dfc --- /dev/null +++ b/src/ast/constref.js @@ -0,0 +1,21 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ + +var Expr = require('./expression'); +var KIND = 'constref'; + +/** + * A constant reference + * @constructor ConstRef + * @extends {Expression} + * @property {String|Node} name + */ +var ConstRef = Expr.extends(function ConstRef(identifier, location) { + Expr.apply(this, [KIND, location]); + this.name = identifier; +}); + +module.exports = ConstRef; diff --git a/src/ast/continue.js b/src/ast/continue.js new file mode 100644 index 000000000..f2be946e5 --- /dev/null +++ b/src/ast/continue.js @@ -0,0 +1,19 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; +var Node = require('./node'); +var KIND = 'continue'; + +/** + * A continue statement + * @constructor Continue + * @extends {Node} + */ +var Continue = Node.extends(function Continue(location) { + Node.apply(this, [KIND, location]); +}); + +module.exports = Continue; diff --git a/src/ast/declaration.js b/src/ast/declaration.js index fb1c81097..b3d64a434 100644 --- a/src/ast/declaration.js +++ b/src/ast/declaration.js @@ -28,7 +28,18 @@ var Declaration = Statement.extends(function Declaration(kind, name, location) { * @return {void} */ Declaration.prototype.parseFlags = function(flags) { - // @todo + this.isAbstract = flags[2] === 1; + this.isFinal = flags[2] === 2; + if (this.kind !== 'class') { + if (flags[0] === 0) { + this.visibility = IS_PUBLIC; + } else if (flags[0] === 1) { + this.visibility = IS_PROTECTED; + } else if (flags[0] === 2) { + this.visibility = IS_PRIVATE; + } + this.isStatic = flags[1] === 1; + } }; module.exports = Declaration; diff --git a/src/ast/do.js b/src/ast/do.js new file mode 100644 index 000000000..1e4a7902d --- /dev/null +++ b/src/ast/do.js @@ -0,0 +1,24 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +var Statement = require('./statement'); +var KIND = 'do'; + +/** + * Defines a do/while statement + * @constructor Do + * @extends {Statement} + * @property {Expression} test + * @property {Statement} body + */ +var Do = Statement.extends(function Do(test, body, location) { + Statement.apply(this, [KIND, location]); + this.test = test; + this.body = body; +}); + +module.exports = Do; diff --git a/src/ast/documentation.js b/src/ast/doc.js similarity index 64% rename from src/ast/documentation.js rename to src/ast/doc.js index 09935e821..3c989fbfd 100644 --- a/src/ast/documentation.js +++ b/src/ast/doc.js @@ -12,12 +12,12 @@ var KIND = 'doc'; * @constructor Documentation * @extends {Node} * @property {Boolean} isDoc - * @property {String} text + * @property {String[]} lines */ -var Documentation = Node.extends(function Documentation(text, location) { +var Doc = Node.extends(function Doc(isDoc, lines, location) { Node.apply(this, [KIND, location]); - this.isDoc = text.substring(0, 2) === '/*'; - this.text = text; + this.isDoc = isDoc; + this.lines = lines; }); -module.exports = Statement; +module.exports = Doc; diff --git a/src/ast/for.js b/src/ast/for.js new file mode 100644 index 000000000..6861bdc67 --- /dev/null +++ b/src/ast/for.js @@ -0,0 +1,31 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +var Statement = require('./statement'); +var KIND = 'for'; + +/** + * Defines a for iterator + * @constructor For + * @extends {Statement} + * @property {Expression[]} init + * @property {Expression[]} test + * @property {Expression[]} increment + * @property {Statement} body + * @property {boolean} shortForm + * @see http://php.net/manual/en/control-structures.for.php + */ +var For = Statement.extends(function For(init, test, increment, body, shortForm, location) { + Statement.apply(this, [KIND, location]); + this.init = init; + this.test = test; + this.increment = increment; + this.shortForm = shortForm; + this.body = body; +}); + +module.exports = For; diff --git a/src/ast/foreach.js b/src/ast/foreach.js new file mode 100644 index 000000000..101543dbc --- /dev/null +++ b/src/ast/foreach.js @@ -0,0 +1,31 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +var Statement = require('./statement'); +var KIND = 'foreach'; + +/** + * Defines a foreach iterator + * @constructor Foreach + * @extends {Statement} + * @property {Expression} source + * @property {Expression|null} key + * @property {Expression} value + * @property {Statement} body + * @property {boolean} shortForm + * @see http://php.net/manual/en/control-structures.foreach.php + */ +var Foreach = Statement.extends(function Foreach(source, key, value, body, shortForm, location) { + Statement.apply(this, [KIND, location]); + this.source = source; + this.key = key; + this.value = value; + this.shortForm = shortForm; + this.body = body; +}); + +module.exports = Foreach; diff --git a/src/ast/function.js b/src/ast/function.js index 0a390d12a..c082b9394 100644 --- a/src/ast/function.js +++ b/src/ast/function.js @@ -5,22 +5,24 @@ */ var Declaration = require('./declaration'); -var KIND = 'method'; +var KIND = 'function'; /** * Defines a classic function * @constructor Function * @extends {Declaration} - * @property {Argument[]} arguments + * @property {Parameter[]} arguments * @property {Identifier} type * @property {boolean} byref - * @property {Node[]} children + * @property {boolean} nullable + * @property {Block|null} body */ -var fn = Declaration.extends(function _Function(name, args, byref, type, location) { +var fn = Declaration.extends(function _Function(name, args, byref, type, nullable, location) { Declaration.apply(this, [KIND, name, location]); this.arguments = args; this.byref = byref; this.type = type; - this.children = []; + this.nullable = nullable; + this.body = null; }); module.exports = fn; diff --git a/src/ast/global.js b/src/ast/global.js new file mode 100644 index 000000000..691309eb9 --- /dev/null +++ b/src/ast/global.js @@ -0,0 +1,21 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; +var Statement = require('./statement'); +var KIND = 'global'; + +/** + * Imports a variable from the global scope + * @constructor Global + * @extends {Statement} + * @property {Variable[]} items + */ +var Global = Statement.extends(function Global(items, location) { + Statement.apply(this, [KIND, location]); + this.items = items; +}); + +module.exports = Global; diff --git a/src/ast/goto.js b/src/ast/goto.js new file mode 100644 index 000000000..e58509c0c --- /dev/null +++ b/src/ast/goto.js @@ -0,0 +1,23 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +var Statement = require('./statement'); +var KIND = 'goto'; + +/** + * Defines goto statement + * @constructor Goto + * @extends {Statement} + * @property {String} label + * @see {Label} + */ +var Goto = Statement.extends(function Goto(label, location) { + Statement.apply(this, [KIND, location]); + this.label = label; +}); + +module.exports = Goto; diff --git a/src/ast/identifier.js b/src/ast/identifier.js index 3222249ad..8510e092d 100644 --- a/src/ast/identifier.js +++ b/src/ast/identifier.js @@ -7,22 +7,49 @@ var Node = require('./node'); var KIND = 'identifier'; - /** * Defines an identifier node * @constructor Identifier * @extends {Node} * @property {string} name - * @property {boolean} fqn + * @property {string} resolution */ -var Identifier = Node.extends(function Identifier(name, fqn, location) { +var Identifier = Node.extends(function Identifier(name, isRelative, location) { Node.apply(this, [KIND, location]); - this.name = Array.isArray(name) ? name.join('\\') : name; - if (typeof fqn !== 'boolean') { - this.fqn = this.name[0] === '\\'; + if (isRelative) { + this.resolution = Identifier.RELATIVE_NAME; + } else if (name.length === 1) { + this.resolution = Identifier.UNQUALIFIED_NAME; + } else if (name[0] === '') { + this.resolution = Identifier.FULL_QUALIFIED_NAME; } else { - this.fqn = fqn; + this.resolution = Identifier.QUALIFIED_NAME; } + this.name = name.join('\\'); }); +/** + * This is an identifier without a namespace separator, such as Foo + * @constant {String} UNQUALIFIED_NAME + */ +Identifier.UNQUALIFIED_NAME = 'uqn'; +/** + * This is an identifier with a namespace separator, such as Foo\Bar + * @constant {String} QUALIFIED_NAME + */ +Identifier.QUALIFIED_NAME = 'qn'; +/** + * This is an identifier with a namespace separator that begins with + * a namespace separator, such as \Foo\Bar. The namespace \Foo is also + * a fully qualified name. + * @constant {String} FULL_QUALIFIED_NAME + */ +Identifier.FULL_QUALIFIED_NAME = 'fqn'; +/** + * This is an identifier starting with namespace, such as namespace\Foo\Bar. + * @constant {String} RELATIVE_NAME + */ +Identifier.RELATIVE_NAME = 'rn'; + + module.exports = Identifier; diff --git a/src/ast/if.js b/src/ast/if.js new file mode 100644 index 000000000..2bc99007f --- /dev/null +++ b/src/ast/if.js @@ -0,0 +1,28 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +var Statement = require('./statement'); +var KIND = 'if'; + +/** + * Defines a if statement + * @constructor If + * @extends {Statement} + * @property {Expression} test + * @property {Block} body + * @property {Block|If|null} alternate + * @property {boolean} shortForm + */ +var If = Statement.extends(function If(test, body, alternate, shortForm, location) { + Statement.apply(this, [KIND, location]); + this.test = test; + this.body = body; + this.alternate = alternate; + this.shortForm = shortForm; +}); + +module.exports = If; diff --git a/src/ast/interface.js b/src/ast/interface.js new file mode 100644 index 000000000..c218427c4 --- /dev/null +++ b/src/ast/interface.js @@ -0,0 +1,24 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ + +var Declaration = require('./declaration'); +var KIND = 'interface'; + + +/** + * An interface definition + * @constructor Interface + * @extends {Declaration} + * @property {Identifier[]} extends + * @property {Declaration[]} body + */ +var Interface = Declaration.extends(function Interface(name, ext, body, location) { + Declaration.apply(this, [KIND, name, location]); + this.extends = ext; + this.body = body; +}); + +module.exports = Interface; diff --git a/src/ast/label.js b/src/ast/label.js new file mode 100644 index 000000000..5c86d2b78 --- /dev/null +++ b/src/ast/label.js @@ -0,0 +1,21 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; +var Node = require('./node'); +var KIND = 'label'; + +/** + * A label statement (referenced by goto) + * @constructor Label + * @extends {Node} + * @property {String} name + */ +var Label = Node.extends(function Label(name, location) { + Node.apply(this, [KIND, location]); + this.name = name; +}); + +module.exports = Label; diff --git a/src/ast/list.js b/src/ast/list.js new file mode 100644 index 000000000..82bc3523b --- /dev/null +++ b/src/ast/list.js @@ -0,0 +1,19 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ + +var Sys = require('./sys'); +var KIND = 'list'; + +/** + * Defines list assignment + * @constructor List + * @extends {Sys} + */ +var List = Sys.extends(function List(args, location) { + Sys.apply(this, [KIND, args, location]); +}); + +module.exports = List; diff --git a/src/ast/literal.js b/src/ast/literal.js index 5e70b98de..5380a90c4 100644 --- a/src/ast/literal.js +++ b/src/ast/literal.js @@ -9,7 +9,7 @@ var KIND = 'literal'; /** * Defines an array structure - * @constructor ArrayExpression + * @constructor Literal * @extends {Expression} * @property {Node|string|number|boolean|null} value */ diff --git a/src/ast/lookup.js b/src/ast/lookup.js new file mode 100644 index 000000000..e8fc3e0e0 --- /dev/null +++ b/src/ast/lookup.js @@ -0,0 +1,23 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ + +var Expr = require('./expression'); +var KIND = 'lookup'; + +/** + * Lookup on an offset in the specified object + * @constructor Lookup + * @extends {Expression} + * @property {Expression} what + * @property {Expression} offset + */ +var Lookup = Expr.extends(function Lookup(kind, what, offset, location) { + Expr.apply(this, [kind || KIND, location]); + this.what = what; + this.offset = offset; +}); + +module.exports = Lookup; diff --git a/src/ast/new.js b/src/ast/new.js new file mode 100644 index 000000000..22a317af1 --- /dev/null +++ b/src/ast/new.js @@ -0,0 +1,24 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +var Statement = require('./statement'); +var KIND = 'new'; + +/** + * Creates a new instance of the specified class + * @constructor New + * @extends {Statement} + * @property {Identifier|Variable|Class} what + * @property {Arguments[]} arguments + */ +var New = Statement.extends(function New(what, args, location) { + Statement.apply(this, [KIND, location]); + this.what = what; + this.arguments = args; +}); + +module.exports = New; diff --git a/src/ast/offsetlookup.js b/src/ast/offsetlookup.js new file mode 100644 index 000000000..198c96ee7 --- /dev/null +++ b/src/ast/offsetlookup.js @@ -0,0 +1,19 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; +var Lookup = require('./lookup'); +var KIND = 'offsetlookup'; + +/** + * Lookup on an offset in an array + * @constructor OffsetLookup + * @extends {Lookup} + */ +var OffsetLookup = Lookup.extends(function OffsetLookup(what, offset, location) { + Lookup.apply(this, [KIND, what, offset, location]); +}); + +module.exports = OffsetLookup; diff --git a/src/ast/operation.js b/src/ast/operation.js new file mode 100644 index 000000000..ad5a007dd --- /dev/null +++ b/src/ast/operation.js @@ -0,0 +1,20 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +var Expr = require('./expression'); +var KIND = 'operation'; + +/** + * Defines binary operations + * @constructor Operation + * @extends {Expression} + */ +var Operation = Expr.extends(function Operation(kind, location) { + Expr.apply(this, [kind || KIND, location]); +}); + +module.exports = Operation; diff --git a/src/ast/parameter.js b/src/ast/parameter.js index 9b5da4850..d2b6222fc 100644 --- a/src/ast/parameter.js +++ b/src/ast/parameter.js @@ -15,13 +15,15 @@ var KIND = 'parameter'; * @property {Node|null} value * @property {boolean} byref * @property {boolean} variadic + * @property {boolean} nullable */ -var Parameter = Declaration.extends(function Parameter(name, type, value, isRef, isVariadic, location) { +var Parameter = Declaration.extends(function Parameter(name, type, value, isRef, isVariadic, nullable, location) { Declaration.apply(this, [KIND, name, location]); this.value = value; this.type = type; this.byref = isRef; this.variadic = isVariadic; + this.nullable = nullable; }); module.exports = Parameter; diff --git a/src/ast/post.js b/src/ast/post.js new file mode 100644 index 000000000..1ec35fc62 --- /dev/null +++ b/src/ast/post.js @@ -0,0 +1,24 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +var Operation = require('./operation'); +var KIND = 'post'; + +/** + * Defines a post operation `$i++` or `$i--` + * @constructor Post + * @extends {Operation} + * @property {String} type + * @property {Variable} what + */ +var Post = Operation.extends(function Post(type, what, location) { + Operation.apply(this, [KIND, location]); + this.type = type; + this.what = what; +}); + +module.exports = Post; diff --git a/src/ast/pre.js b/src/ast/pre.js new file mode 100644 index 000000000..e5454a06a --- /dev/null +++ b/src/ast/pre.js @@ -0,0 +1,24 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +var Operation = require('./operation'); +var KIND = 'pre'; + +/** + * Defines a pre operation `++$i` or `--$i` + * @constructor Pre + * @extends {Operation} + * @property {String} type + * @property {Variable} what + */ +var Pre = Operation.extends(function Pre(type, what, location) { + Operation.apply(this, [KIND, location]); + this.type = type; + this.what = what; +}); + +module.exports = Pre; diff --git a/src/ast/propertylookup.js b/src/ast/propertylookup.js new file mode 100644 index 000000000..fe38314d9 --- /dev/null +++ b/src/ast/propertylookup.js @@ -0,0 +1,19 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; +var Lookup = require('./lookup'); +var KIND = 'propertylookup'; + +/** + * Lookup to an object property + * @constructor PropertyLookup + * @extends {Lookup} + */ +var PropertyLookup = Lookup.extends(function PropertyLookup(what, offset, location) { + Lookup.apply(this, [KIND, what, offset, location]); +}); + +module.exports = PropertyLookup; diff --git a/src/ast/retif.js b/src/ast/retif.js new file mode 100644 index 000000000..dafcf4052 --- /dev/null +++ b/src/ast/retif.js @@ -0,0 +1,26 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +var Statement = require('./statement'); +var KIND = 'retif'; + +/** + * Defines a short if statement that returns a value + * @constructor RetIf + * @extends {Statement} + * @property {Expression} test + * @property {Expression} trueExpr + * @property {Expression} falseExpr + */ +var RetIf = Statement.extends(function RetIf(test, trueExpr, falseExpr, location) { + Statement.apply(this, [KIND, location]); + this.test = test; + this.trueExpr = trueExpr; + this.falseExpr = falseExpr; +}); + +module.exports = RetIf; diff --git a/src/ast/return.js b/src/ast/return.js new file mode 100644 index 000000000..cc456fda8 --- /dev/null +++ b/src/ast/return.js @@ -0,0 +1,21 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; +var Node = require('./node'); +var KIND = 'return'; + +/** + * A continue statement + * @constructor Return + * @extends {Node} + * @property {Expression|null} expr + */ +var Return = Node.extends(function Return(expr, location) { + Node.apply(this, [KIND, location]); + this.expr = expr; +}); + +module.exports = Return; diff --git a/src/ast/silent.js b/src/ast/silent.js new file mode 100644 index 000000000..6df0c3384 --- /dev/null +++ b/src/ast/silent.js @@ -0,0 +1,22 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +var Statement = require('./statement'); +var KIND = 'silent'; + +/** + * Avoids to show/log warnings & notices from the inner expression + * @constructor Silent + * @extends {Statement} + * @property {Expression} expr + */ +var Silent = Statement.extends(function Silent(expr, location) { + Statement.apply(this, [KIND, location]); + this.expr = expr; +}); + +module.exports = Silent; diff --git a/src/ast/staticlookup.js b/src/ast/staticlookup.js new file mode 100644 index 000000000..4c40ea650 --- /dev/null +++ b/src/ast/staticlookup.js @@ -0,0 +1,19 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; +var Lookup = require('./lookup'); +var KIND = 'staticlookup'; + +/** + * Lookup to a static property + * @constructor StaticLookup + * @extends {Lookup} + */ +var StaticLookup = Lookup.extends(function StaticLookup(what, offset, location) { + Lookup.apply(this, [KIND, what, offset, location]); +}); + +module.exports = StaticLookup; diff --git a/src/ast/switch.js b/src/ast/switch.js new file mode 100644 index 000000000..2126d9d3c --- /dev/null +++ b/src/ast/switch.js @@ -0,0 +1,26 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +var Statement = require('./statement'); +var KIND = 'switch'; + +/** + * Defines a switch statement + * @constructor Switch + * @extends {Statement} + * @property {Expression} test + * @property {Block} body + * @property {boolean} shortForm + */ +var Switch = Statement.extends(function Switch(test, body, shortForm, location) { + Statement.apply(this, [KIND, location]); + this.test = test; + this.body = body; + this.shortForm = shortForm; +}); + +module.exports = Switch; diff --git a/src/ast/trait.js b/src/ast/trait.js new file mode 100644 index 000000000..ae2a5a18a --- /dev/null +++ b/src/ast/trait.js @@ -0,0 +1,26 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ + +var Declaration = require('./declaration'); +var KIND = 'trait'; + + +/** + * A trait definition + * @constructor Trait + * @extends {Declaration} + * @property {Identifier|null} extends + * @property {Identifier[]} implements + * @property {Declaration[]} body + */ +var Trait = Declaration.extends(function Trait(name, ext, impl, body, location) { + Declaration.apply(this, [KIND, name, location]); + this.extends = ext; + this.implements = impl; + this.body = body; +}); + +module.exports = Trait; diff --git a/src/ast/traitalias.js b/src/ast/traitalias.js new file mode 100644 index 000000000..fd28214d5 --- /dev/null +++ b/src/ast/traitalias.js @@ -0,0 +1,41 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ + +var Node = require('./node'); +var KIND = 'traitalias'; + +var IS_PUBLIC = 'public'; +var IS_PROTECTED = 'protected'; +var IS_PRIVATE = 'private'; + +/** + * Defines a trait alias + * @constructor TraitAlias + * @extends {Node} + * @property {Identifier|null} trait + * @property {string} method + * @property {string|null} as + * @property {string|null} visibility + */ +var TraitAlias = Node.extends(function TraitAlias(trait, method, as, flags, location) { + Node.apply(this, [KIND, location]); + this.trait = trait; + this.method = method; + this.as = as; + if (flags) { + if (flags[0] === 0) { + this.visibility = IS_PUBLIC; + } else if (flags[0] === 1) { + this.visibility = IS_PROTECTED; + } else { + this.visibility = IS_PRIVATE; + } + } else { + this.visibility = null; + } +}); + +module.exports = TraitAlias; diff --git a/src/ast/traitprecedence.js b/src/ast/traitprecedence.js new file mode 100644 index 000000000..a5bd405c9 --- /dev/null +++ b/src/ast/traitprecedence.js @@ -0,0 +1,25 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ + +var Node = require('./node'); +var KIND = 'traitprecedence'; + +/** + * Defines a trait alias + * @constructor TraitPrecedence + * @extends {Node} + * @property {Identifier|null} trait + * @property {string} method + * @property {Identifier[]} instead + */ +var TraitPrecedence = Node.extends(function TraitPrecedence(trait, method, instead, location) { + Node.apply(this, [KIND, location]); + this.trait = trait; + this.method = method; + this.instead = instead; +}); + +module.exports = TraitPrecedence; diff --git a/src/ast/traituse.js b/src/ast/traituse.js new file mode 100644 index 000000000..d30610764 --- /dev/null +++ b/src/ast/traituse.js @@ -0,0 +1,23 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ + +var Node = require('./node'); +var KIND = 'traituse'; + +/** + * Defines a trait usage + * @constructor TraitUse + * @extends {Node} + * @property {Identifier[]} traits + * @property {Node[]|null} adaptations + */ +var TraitUse = Node.extends(function TraitUse(traits, adaptations, location) { + Node.apply(this, [KIND, location]); + this.traits = traits; + this.adaptations = adaptations; +}); + +module.exports = TraitUse; diff --git a/src/ast/try.js b/src/ast/try.js new file mode 100644 index 000000000..dc4dd0e0c --- /dev/null +++ b/src/ast/try.js @@ -0,0 +1,26 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +var Statement = require('./statement'); +var KIND = 'try'; + +/** + * Defines a try statement + * @constructor Try + * @extends {Statement} + * @property {Block} body + * @property {Catch[]} catches + * @property {Block} allways + */ +var Try = Statement.extends(function Try(body, catches, always, location) { + Statement.apply(this, [KIND, location]); + this.body = body; + this.catches = catches; + this.always = always; +}); + +module.exports = Try; diff --git a/src/ast/unary.js b/src/ast/unary.js new file mode 100644 index 000000000..bfd8e3422 --- /dev/null +++ b/src/ast/unary.js @@ -0,0 +1,24 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +var Operation = require('./operation'); +var KIND = 'unary'; + +/** + * Unary operations + * @constructor Unary + * @extends {Operation} + * @property {String} type + * @property {Expression} what + */ +var Unary = Operation.extends(function Unary(type, what, location) { + Operation.apply(this, [KIND, location]); + this.type = type; + this.what = what; +}); + +module.exports = Unary; diff --git a/src/ast/usegroup.js b/src/ast/usegroup.js new file mode 100644 index 000000000..0d35e3222 --- /dev/null +++ b/src/ast/usegroup.js @@ -0,0 +1,27 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; +var Statement = require('./statement'); +var KIND = 'usegroup'; + +/** + * Defines a use statement (with a list of use items) + * @constructor UseGroup + * @extends {Statement} + * @property {Identifier|null} name + * @property {String|null} type - Possible value : function, const + * @property {UseItem[]} item + * @see {Namespace} + * @see http://php.net/manual/en/language.namespaces.importing.php + */ +var UseGroup = Statement.extends(function UseGroup(name, type, items, location) { + Statement.apply(this, [KIND, location]); + this.name = name; + this.type = type; + this.items = items; +}); + +module.exports = UseGroup; diff --git a/src/ast/useitem.js b/src/ast/useitem.js new file mode 100644 index 000000000..aee62a2e8 --- /dev/null +++ b/src/ast/useitem.js @@ -0,0 +1,40 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; +var Statement = require('./statement'); +var KIND = 'useitem'; + +/** + * Defines a use statement (from namespace) + * @constructor UseItem + * @extends {Statement} + * @property {Identifier} name + * @property {String|null} type - Possible value : function, const + * @property {String|null} alias + * @see {Namespace} + * @see http://php.net/manual/en/language.namespaces.importing.php + */ +var UseItem = Statement.extends(function UseItem(name, alias, type, location) { + Statement.apply(this, [KIND, location]); + this.name = name; + this.alias = alias; + this.type = type; +}); + + +/** + * Importing a constant + * @constant {String} TYPE_CONST + */ +UseItem.TYPE_CONST = 'const'; +/** + * Importing a function + * @constant {String} TYPE_FUNC + */ +UseItem.TYPE_FUNCTION = 'function'; + + +module.exports = UseItem; diff --git a/src/ast/variable.js b/src/ast/variable.js index 3cf2824f9..94200e15b 100644 --- a/src/ast/variable.js +++ b/src/ast/variable.js @@ -3,7 +3,7 @@ * @authors https://github.com/glayzzle/php-parser/graphs/contributors * @url http://glayzzle.com */ - +"use strict"; var Expr = require('./expression'); var KIND = 'variable'; @@ -12,12 +12,12 @@ var KIND = 'variable'; * be any expression in general, an expression can also be a pattern. * @constructor Variable * @extends {Expression} - * @property {String|Node} identifier + * @property {String|Node} name * @property {boolean} byref */ -var Variable = Expr.extends(function Variable(identifier, byref, location) { +var Variable = Expr.extends(function Variable(name, byref, location) { Expr.apply(this, [KIND, location]); - this.identifier = identifier; + this.name = name; this.byref = byref || false; }); diff --git a/src/ast/while.js b/src/ast/while.js new file mode 100644 index 000000000..9ff909594 --- /dev/null +++ b/src/ast/while.js @@ -0,0 +1,26 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +var Statement = require('./statement'); +var KIND = 'while'; + +/** + * Defines a while statement + * @constructor While + * @extends {Statement} + * @property {Expression} test + * @property {Statement} body + * @property {boolean} shortForm + */ +var While = Statement.extends(function While(test, body, shortForm, location) { + Statement.apply(this, [KIND, location]); + this.test = test; + this.body = body; + this.shortForm = shortForm; +}); + +module.exports = While; diff --git a/src/lexer.js b/src/lexer.js index 464f1edcf..ec880dfe2 100644 --- a/src/lexer.js +++ b/src/lexer.js @@ -3,7 +3,7 @@ * @authors https://github.com/glayzzle/php-parser/graphs/contributors * @url http://glayzzle.com */ - +"use strict"; /** * This is the php lexer. It will tokenize the string for helping the * parser to build the AST from its grammar. @@ -22,6 +22,7 @@ var lexer = function(engine) { this.engine = engine; this.tok = this.engine.tokens.names; this.EOF = 1; + this.debug = false; this.all_tokens = true; this.comment_tokens = false; this.mode_eval = false; @@ -134,6 +135,9 @@ lexer.prototype.setInput = function(input) { first_offset: 0, first_line: 1, first_column: 0, + prev_offset: 0, + prev_line: 1, + prev_column: 0, last_line: 1, last_column: 0 }; @@ -186,6 +190,8 @@ lexer.prototype.unput = function(size) { this.yylloc.last_line --; this.yylineno --; this.yylloc.last_column = this.yyprevcol; + } else { + this.yylloc.last_column --; } this.yytext = this.yytext.substring(0, this.yytext.length - size); } else if (size > 0) { @@ -194,27 +200,27 @@ lexer.prototype.unput = function(size) { this.yytext = this.yytext.substring(0, this.yytext.length - size); // re-calculate position this.yylloc.last_line = this.yylloc.first_line; - this.yylloc.last_col = this.yyprevcol = this.yylloc.first_col; + this.yylloc.last_column = this.yyprevcol = this.yylloc.first_column; for(var i = 0; i < this.yytext.length; i++) { var c = this.yytext[i]; if (c === '\r') { c = this.yytext[++i]; - this.yyprevcol = this.yylloc.last_col; + this.yyprevcol = this.yylloc.last_column; this.yylloc.last_line ++; - this.yylloc.last_col = 0; + this.yylloc.last_column = 0; if (c !== '\n') { if (c === '\r') { this.yylloc.last_line ++; } else { - this.yylloc.last_col ++; + this.yylloc.last_column ++; } } } else if (c === '\n') { - this.yyprevcol = this.yylloc.last_col; + this.yyprevcol = this.yylloc.last_column; this.yylloc.last_line ++; - this.yylloc.last_col = 0; + this.yylloc.last_column = 0; } else { - this.yylloc.last_col ++; + this.yylloc.last_column ++; } } this.yylineno = this.yylloc.last_line; @@ -310,6 +316,9 @@ lexer.prototype.appendToken = function(value, ahead) { // return next match that has a token lexer.prototype.lex = function() { + this.yylloc.prev_offset = this.offset; + this.yylloc.prev_line = this.yylloc.last_line; + this.yylloc.prev_column = this.yylloc.last_column; var token = this.next() || this.lex(); if (!this.all_tokens) { while( @@ -321,10 +330,8 @@ lexer.prototype.lex = function() { ) ) || ( - !this.mode_eval // ignore open/close tags - && token === this.tok.T_OPEN_TAG - // || token === this.tok.T_CLOSE_TAG - // ) + // ignore open tags + token === this.tok.T_OPEN_TAG ) ) { token = this.next() || this.lex(); @@ -334,6 +341,11 @@ lexer.prototype.lex = function() { return this.tok.T_ECHO; } } + if (!this.yylloc.prev_offset) { + this.yylloc.prev_offset = this.yylloc.first_offset; + this.yylloc.prev_line = this.yylloc.first_line; + this.yylloc.prev_column = this.yylloc.first_column; + } return token; }; @@ -366,13 +378,16 @@ lexer.prototype.next = function () { if (!this._input) { this.done = true; } - if (this.done) { - return this.EOF; - } this.yylloc.first_offset = this.offset; this.yylloc.first_line = this.yylloc.last_line; this.yylloc.first_column = this.yylloc.last_column; this.yytext = ''; + if (this.done) { + this.yylloc.prev_offset = this.yylloc.first_offset; + this.yylloc.prev_line = this.yylloc.first_line; + this.yylloc.prev_column = this.yylloc.first_column; + return this.EOF; + } if (this.tokens.length > 0) { token = this.tokens.shift(); if (typeof token[1] === 'object') { @@ -387,6 +402,19 @@ lexer.prototype.next = function () { if (this.offset >= this.size && this.tokens.length === 0) { this.done = true; } + if (this.debug) { + var tName = token; + if (typeof tName === 'number') { + tName = this.engine.tokens.values[tName]; + } else { + tName = '"'+tName+'"'; + } + console.log( + tName, + 'from ' + this.yylloc.first_line + ',' + this.yylloc.first_column, + ' - to ' + this.yylloc.last_line + ',' + this.yylloc.last_column + ); + } return token; }; diff --git a/src/lexer/comments.js b/src/lexer/comments.js index 71e9c009b..69673e629 100644 --- a/src/lexer/comments.js +++ b/src/lexer/comments.js @@ -3,7 +3,14 @@ * @authors https://github.com/glayzzle/php-parser/graphs/contributors * @url http://glayzzle.com */ + +"use strict"; + module.exports = { + /** + * Reads a single line comment + * @see + */ T_COMMENT: function() { while(this.offset < this.size) { var ch = this.input(); @@ -14,7 +21,7 @@ module.exports = { return this.tok.T_COMMENT; } else if (ch === '%' && this.aspTagMode && this._input[this.offset] === '>') { this.unput(1); - return tthis.tok.T_COMMENT; + return this.tok.T_COMMENT; } } return this.tok.T_COMMENT; diff --git a/src/lexer/numbers.js b/src/lexer/numbers.js index 0db6d621b..4b40432b2 100644 --- a/src/lexer/numbers.js +++ b/src/lexer/numbers.js @@ -4,14 +4,16 @@ * @url http://glayzzle.com */ -// DEFINE LONG SIZE +"use strict"; + +/* istanbul ignore else */ if (process.arch == 'x64') { var SIZEOF_LONG = 8; - var MAX_LENGTH_OF_LONG = 20; + var MAX_LENGTH_OF_LONG = 19; var long_min_digits = "9223372036854775808"; } else { var SIZEOF_LONG = 4; - var MAX_LENGTH_OF_LONG = 11; + var MAX_LENGTH_OF_LONG = 10; var long_min_digits = "2147483648"; } @@ -76,8 +78,10 @@ module.exports = { return this.tok.T_LNUMBER; } else { if ( - this.yytext.length == MAX_LENGTH_OF_LONG - && this.yytext < long_min_digits + this.yytext.length < MAX_LENGTH_OF_LONG || ( + this.yytext.length == MAX_LENGTH_OF_LONG + && this.yytext < long_min_digits + ) ) { return this.tok.T_LNUMBER; } diff --git a/src/lexer/strings.js b/src/lexer/strings.js index 920c10645..9f9b29d91 100644 --- a/src/lexer/strings.js +++ b/src/lexer/strings.js @@ -134,6 +134,7 @@ module.exports = { matchST_NOWDOC: function() { /** edge case : empty now doc **/ if (this.isDOC_MATCH()) { + // @fixme : never reached (may be caused by quotes) this.consume(this.heredoc_label.length); this.popState(); return this.tok.T_END_HEREDOC; @@ -274,9 +275,9 @@ module.exports = { this.begin('ST_IN_SCRIPTING'); return this.tok.T_CURLY_OPEN; } - } else if (ch === '"') { + } else if (ch === '`') { this.popState(); - return '"'; + return '`'; } // any char @@ -399,6 +400,7 @@ module.exports = { this.unput(2); return this.tok.T_ENCAPSED_AND_WHITESPACE; } else { + // @fixme : yytext = '"{$' (this.yytext.length > 3) this.unput(1); return this.tok.T_CURLY_OPEN; } diff --git a/src/parser.js b/src/parser.js index 5aaeb4ac8..ca54eb02b 100644 --- a/src/parser.js +++ b/src/parser.js @@ -53,6 +53,7 @@ var parser = function(lexer, ast) { this.tok.T_FILE, this.tok.T_DIR, this.tok.T_NS_C, + this.tok.T_NAMESPACE, '"', 'b"', 'B"', @@ -79,7 +80,7 @@ var parser = function(lexer, ast) { ], 'VARIABLE': [ this.tok.T_VARIABLE, - '$', + '$', '&', this.tok.T_NS_SEPARATOR, this.tok.T_STRING, this.tok.T_STATIC @@ -182,6 +183,7 @@ parser.prototype.parse = function(code) { * Raise an error */ parser.prototype.raiseError = function(message, msgExpect, expect, token) { + message += ' on line ' + this.lexer.yylloc.first_line; if (!this.suppressErrors) { throw new Error(message); } @@ -218,7 +220,7 @@ parser.prototype.error = function(expect) { } this.token !== this.EOF return this.raiseError( - msg + ' on line ' + this.lexer.yylloc.first_line, + msg, msgExpect, expect, token @@ -234,6 +236,7 @@ parser.prototype.node = function(name) { /** * expects an end of statement or end of file + * @return {boolean} */ parser.prototype.expectEndOfStatement = function() { if (this.token === ';') { @@ -246,8 +249,9 @@ parser.prototype.expectEndOfStatement = function() { this.nextWithComments(); } else if (this.token !== this.tok.T_INLINE_HTML && this.token !== this.EOF) { this.error(';'); + return false; } - return this; + return true; }; /** outputs some debug information on current token **/ @@ -290,7 +294,7 @@ parser.prototype.showlog = function() { * be added to the program error stack and this function will return `false`. * * @param {String|Number} token - * @return {Parser|False} + * @return {boolean} * @throws Error */ parser.prototype.expect = function(token) { @@ -303,7 +307,7 @@ parser.prototype.expect = function(token) { this.error(token); return false; } - return this; + return true; }; /** @@ -370,44 +374,11 @@ parser.prototype.read_token = function() { return result; }; -/** - * Helper : reads a list of tokens / sample : T_STRING ',' T_STRING ... - * ```ebnf - * list ::= separator? ( item separator )* item - * ``` - */ -parser.prototype.read_list = function(item, separator, preserveFirstSeparator) { - var result = []; - - if (this.token == separator) { - if (preserveFirstSeparator) result.push(''); - this.next(); - } - - if (typeof (item) === "function") { - do { - result.push(item.apply(this, [])); - if (this.token != separator) { - break; - } - } while(this.next().token != this.EOF); - } else { - result.push(this.expect(item).text()); - while (this.next().token != this.EOF) { - if (this.token != separator) break; - // trim current separator & check item - if (this.next().token != item) break; - result.push(this.text()); - } - } - return result; -}; - - // extends the parser with syntax files [ require('./parser/array.js'), require('./parser/class.js'), + require('./parser/comment.js'), require('./parser/expr.js'), require('./parser/function.js'), require('./parser/if.js'), @@ -418,7 +389,7 @@ parser.prototype.read_list = function(item, separator, preserveFirstSeparator) { require('./parser/statement.js'), require('./parser/switch.js'), require('./parser/try.js'), - require('./parser/comment.js'), + require('./parser/utils.js'), require('./parser/variable.js') ].forEach(function (ext) { for(var k in ext) { diff --git a/src/parser/array.js b/src/parser/array.js index 9680c5c62..5f7de6293 100644 --- a/src/parser/array.js +++ b/src/parser/array.js @@ -20,7 +20,9 @@ module.exports = { var items = []; var result = this.node(ArrayExpr); - if (this.expect([this.tok.T_ARRAY, '[']).token == this.tok.T_ARRAY) { + this.expect([this.tok.T_ARRAY, '[']); + + if (this.token == this.tok.T_ARRAY) { this.next().expect('('); } else { shortForm = true; @@ -36,7 +38,8 @@ module.exports = { } else break; } } - this.expect(shortForm ? ']' : ')').next(); + this.expect(shortForm ? ']' : ')'); + this.next(); return result(shortForm, items); }, /** diff --git a/src/parser/class.js b/src/parser/class.js index 6e0bb020e..fa2e6cf14 100644 --- a/src/parser/class.js +++ b/src/parser/class.js @@ -13,25 +13,21 @@ module.exports = { */ read_class: function(flag) { var result = this.node('class'); - this.expect(this.tok.T_CLASS) - .next() - .expect(this.tok.T_STRING) - ; + this.expect(this.tok.T_CLASS); + this.next().expect(this.tok.T_STRING); var propName = this.text() , propExtends = null - , propImplements = [] + , propImplements = null , body ; if (this.next().token == this.tok.T_EXTENDS) { propExtends = this.next().read_namespace_name(); } if (this.token == this.tok.T_IMPLEMENTS) { - propImplements = this.next().read_list( - this.read_namespace_name, - ',' - ); + propImplements = this.next().read_name_list(); } - body = this.expect('{').nextWithComments().read_class_body(); + this.expect('{'); + body = this.nextWithComments().read_class_body(); return result( propName ,propExtends @@ -50,12 +46,12 @@ module.exports = { var result = this.token; if (result == this.tok.T_FINAL) { this.next(); - return -1; + return [0, 0, 2]; } else if (result == this.tok.T_ABSTRACT) { this.next(); - return 1; + return [0, 0, 1]; } - return 0; + return [0, 0, 0]; } /** * Reads a class body @@ -92,7 +88,8 @@ module.exports = { // check constant if (this.token === this.tok.T_CONST) { var constants = this.read_constant_list(flags); - this.expect(';').nextWithComments(); + this.expect(';'); + this.nextWithComments(); result = result.concat(constants); continue; } @@ -107,7 +104,8 @@ module.exports = { // reads a variable var variables = this.read_variable_list(flags); - this.expect(';').nextWithComments(); + this.expect(';'); + this.nextWithComments(); result = result.concat(variables); } else if (this.token === this.tok.T_FUNCTION) { @@ -128,7 +126,8 @@ module.exports = { } } - this.expect('}').nextWithComments(); + this.expect('}'); + this.nextWithComments(); return result; } /** @@ -148,7 +147,8 @@ module.exports = { */ function read_variable_declaration() { var result = this.node('property'); - var name = this.expect(this.tok.T_VARIABLE).text(); + this.expect(this.tok.T_VARIABLE); + var name = this.text(); this.next(); if (this.token === ';' || this.token === ',') { return result(name, null, flags); @@ -169,9 +169,10 @@ module.exports = { * ``` */ ,read_constant_list: function(flags) { - return this.expect(this.tok.T_CONST) - .next() - .read_list( + if (this.expect(this.tok.T_CONST)) { + this.next(); + } + return this.read_list( /** * Reads a constant declaration * @@ -181,9 +182,14 @@ module.exports = { * @return {Constant} [:link:](AST.md#constant) */ function read_constant_declaration() { - var result = this.node('classconstant'); - var name = this.expect(this.tok.T_STRING).text(); - var value = this.next().expect('=').next().read_expr(); + var result = this.node('classconstant'), name = null, value = null; + if (this.expect(this.tok.T_STRING)) { + name = this.text(); + this.next(); + } + if (this.expect('=')) { + value = this.next().read_expr(); + } return result(name, value, flags); }, ',' ) @@ -237,29 +243,25 @@ module.exports = { /** * reading an interface * ```ebnf - * interface ::= class_scope? T_INTERFACE T_STRING (T_EXTENDS (NAMESPACE_NAME ',')* NAMESPACE_NAME)? '{' INTERFACE_BODY '}' + * interface ::= T_INTERFACE T_STRING (T_EXTENDS (NAMESPACE_NAME ',')* NAMESPACE_NAME)? '{' INTERFACE_BODY '}' * ``` */ - ,read_interface: function(flag) { - var result = this.node('interface'); - var name = this.expect(this.tok.T_INTERFACE) - .next() - .expect(this.tok.T_STRING) - .text() - ; - var propExtends = false; - if (this.next().token == this.tok.T_EXTENDS) { - propExtends = this.next().read_list( - this.read_namespace_name, - ',' - ); + ,read_interface: function() { + var result = this.node('interface'), name = null, body = null, propExtends = null; + if (this.expect(this.tok.T_INTERFACE)) { + this.next(); } - return result( - name - , flag - , propExtends - , this.expect('{').next().read_interface_body() - ); + if (this.expect(this.tok.T_STRING)) { + name = this.text(); + this.next(); + } + if (this.token === this.tok.T_EXTENDS) { + propExtends = this.next().read_name_list(); + } + if (this.expect('{')) { + body = this.next().read_interface_body(); + } + return result(name, propExtends, body); } /** * Reads an interface body @@ -273,12 +275,12 @@ module.exports = { while(this.token !== this.EOF && this.token !== '}') { if (this.token === this.tok.T_COMMENT) { - comment = this.read_comment(); + result.push(this.read_comment()); continue; } if (this.token === this.tok.T_DOC_COMMENT) { - comment = this.read_doc_comment(); + result.push(this.read_doc_comment()); continue; } @@ -288,28 +290,32 @@ module.exports = { // check constant if (this.token == this.tok.T_CONST) { var constants = this.read_constant_list(flags); - this.expect(';').nextWithComments(); + if (this.expect(';')) { + this.nextWithComments(); + } result = result.concat(constants); } // reads a function else if (this.token === this.tok.T_FUNCTION) { - var method = this.read_function_declaration(2); - (this.locations ? method[3] : method).push(flags); + var method = this.read_function_declaration(2, flags); + method.parseFlags(flags); result.push(method); - this.expect(';').nextWithComments(); + if (this.expect(';')) { + this.nextWithComments(); + } } else { // raise an error - result.push( - this.error([ - this.tok.T_CONST, - this.tok.T_FUNCTION - ]) - ); + this.error([ + this.tok.T_CONST, + this.tok.T_FUNCTION + ]); this.next(); } } - this.expect('}').next(); + if (this.expect('}')) { + this.next(); + } return result; } /** @@ -319,28 +325,31 @@ module.exports = { * ``` */ ,read_trait: function(flag) { - var result = this.node('trait'); - this.expect(this.tok.T_TRAIT) - .next() - .expect(this.tok.T_STRING) - ; - var propName = this.text(), - propExtends = false, - propImplements = false; + var result = this.node('trait'), + propName = null, + propExtends = null, + propImplements = null, + body = null; + if (this.expect(this.tok.T_TRAIT)) { + this.next(); + } + if (this.expect(this.tok.T_STRING)) { + propName = this.text(); + } if (this.next().token == this.tok.T_EXTENDS) { propExtends = this.next().read_namespace_name(); } if (this.token == this.tok.T_IMPLEMENTS) { - propImplements = this.next().read_list( - this.read_namespace_name, - ',' - ); + propImplements = this.next().read_name_list(); + } + if (this.expect('{')) { + body = this.next().read_class_body(); } return result( propName, propExtends, propImplements, - this.expect('{').next().read_class_body() + body ); } /** @@ -351,26 +360,31 @@ module.exports = { */ ,read_trait_use_statement: function() { // defines use statements - var node = this.node('use'); - var name = this.read_namespace_name(); - var result = [node(name)]; + var node = this.node('traituse'); + var traits = [this.read_namespace_name()]; + var adaptations = null; while(this.token === ',') { - node = this.node('use'); - name = this.next().read_namespace_name(); - result.push(node(name)); + traits.push( + this.next().read_namespace_name() + ); } if (this.token === '{') { + adaptations = []; // defines alias statements - while(this.next()) { + while(this.next().token !== this.EOF) { if (this.token === '}') break; - result.push(this.read_trait_use_alias()); + adaptations.push(this.read_trait_use_alias()); this.expect(';'); } - this.expect('}').nextWithComments(); + if (this.expect('}')) { + this.nextWithComments(); + } } else { - this.expect(';').nextWithComments(); + if (this.expect(';')) { + this.nextWithComments(); + } } - return result; + return node(traits, adaptations); } /** * Reading trait alias @@ -379,43 +393,51 @@ module.exports = { * ``` */ ,read_trait_use_alias: function() { - var node = this.node('alias'); - var origin = this.read_namespace_name(); - var act = false; - var target = false; - var flags = false; + var node = this.node(); + var trait = null; + var method = this.read_namespace_name(); if (this.token === this.tok.T_DOUBLE_COLON) { - origin = [ - 'static', - 'get', - origin, - this.next().expect(this.tok.T_STRING).text() - ]; - this.next(); + if (this.next().expect(this.tok.T_STRING)) { + trait = method; + method = this.text(); + this.next(); + } + } else { + // convert identifier as string + method = method.name; } + // handle trait precedence if (this.token === this.tok.T_INSTEADOF) { - act = 'insteadof'; - target = this.next().read_namespace_name(); - } else if (this.token === this.tok.T_AS) { - act = 'as'; + return node( + 'traitprecedence', + trait, method, + this.next().read_name_list() + ); + } + + // handle trait alias + else if (this.token === this.tok.T_AS) { + var flags = false; + var alias = null; if (this.next().is('T_MEMBER_FLAGS')) { flags = this.read_member_flags(); } + if (this.token === this.tok.T_STRING) { - target = this.text(); + alias = this.text(); this.next(); } else if (flags === false) { // no visibility flags and no name => too bad this.expect(this.tok.T_STRING); } - } else { - this.expect([ - this.tok.T_AS, - this.tok.T_INSTEADOF - ]); + + return node('traitalias', trait, method, alias, flags) } - return node(origin, act, target, flags); + + // handle errors + this.expect([this.tok.T_AS, this.tok.T_INSTEADOF]); + return node('traitalias', trait, method, null, null); } }; diff --git a/src/parser/comment.js b/src/parser/comment.js index 7d8282831..23ad88752 100644 --- a/src/parser/comment.js +++ b/src/parser/comment.js @@ -3,24 +3,43 @@ * @authors https://github.com/glayzzle/php-parser/graphs/contributors * @url http://glayzzle.com */ + +var docSplit = /^(\s*\*[ \t]*|[ \t]*)(.*)$/gm; + module.exports = { /** - * Comments with // or # + * Comments with // or # or / * ... * / */ read_comment: function() { - var result = this.node('comment'); - var input = [this.text()]; - while(this.nextWithComments().token === this.tok.T_COMMENT) { - input.push(this.text()); - } - return result(input); + var result = this.node('doc'); + var lines = []; + do { + var line = this.text(); + if (line[0] === '#') { + line = line.substring(1); + } else { + line = line.substring(2); + if (line.substring(line.length - 2) === '*/') { + line = line.substring(0, line.length - 2); + } + } + lines.push(line.trim()); + } while(this.nextWithComments().token === this.tok.T_COMMENT); + return result(false, lines); }, /** - * Comments with / ** ** / + * Comments with / ** ... * / */ read_doc_comment: function() { - var result = this.node('doc')(this.text()); + var result = this.node('doc'); + var text = this.text(); + text = text.substring(2, text.length - 2); + var lines = []; + text = text.split(docSplit); + for(var i = 2; i < text.length; i += 3) { + lines.push(text[i].trim()); + } this.nextWithComments(); - return result; + return result(true, lines); } }; diff --git a/src/parser/expr.js b/src/parser/expr.js index e33242c16..9be20b6af 100644 --- a/src/parser/expr.js +++ b/src/parser/expr.js @@ -3,61 +3,86 @@ * @authors https://github.com/glayzzle/php-parser/graphs/contributors * @url http://glayzzle.com */ +"use strict"; module.exports = { read_expr: function() { + var result = this.node(); var expr = this.read_expr_item(); - switch(this.token) { - // binary operations - case '|': return this.node('bin')('|', expr, this.next().read_expr()); - case '&': return this.node('bin')('&', expr, this.next().read_expr()); - case '^': return ['bin', '^', expr, this.next().read_expr()]; - case '.': return ['bin', '.', expr, this.next().read_expr()]; - case '+': return ['bin', '+', expr, this.next().read_expr()]; - case '-': return ['bin', '-', expr, this.next().read_expr()]; - case '*': return ['bin', '*', expr, this.next().read_expr()]; - case '/': return ['bin', '/', expr, this.next().read_expr()]; - case '%': return ['bin', '%', expr, this.next().read_expr()]; - case this.tok.T_POW: return ['bin', '**', expr, this.next().read_expr()]; - case this.tok.T_SL: return ['bin', '<<', expr, this.next().read_expr()]; - case this.tok.T_SR: return ['bin', '>>', expr, this.next().read_expr()]; - - // boolean operations - case this.tok.T_BOOLEAN_OR: - case this.tok.T_LOGICAL_OR: return ['bool', '|', expr, this.next().read_expr()]; - - case this.tok.T_BOOLEAN_AND: - case this.tok.T_LOGICAL_AND: return ['bool', '&', expr, this.next().read_expr()]; - - case this.tok.T_LOGICAL_XOR: return ['bool', '^', expr, this.next().read_expr()]; - case this.tok.T_IS_IDENTICAL: return ['bool', '=', expr, this.next().read_expr()]; - case this.tok.T_IS_NOT_IDENTICAL: return ['bool', '!=', expr, this.next().read_expr()]; - case this.tok.T_IS_EQUAL: return ['bool', '~', expr, this.next().read_expr()]; - case this.tok.T_IS_NOT_EQUAL: return ['bool', '!~', expr, this.next().read_expr()]; - case '<': return ['bool', '<', expr, this.next().read_expr()]; - case '>': return ['bool', '>', expr, this.next().read_expr()]; - - case this.tok.T_IS_SMALLER_OR_EQUAL: return ['bool', '<=', expr, this.next().read_expr()]; - case this.tok.T_IS_GREATER_OR_EQUAL: return ['bool', '>=', expr, this.next().read_expr()]; - case this.tok.T_SPACESHIP: return ['bool', '<=>', expr, this.next().read_expr()]; - case this.tok.T_INSTANCEOF: return ['bool', '?', expr, this.next().read_expr()]; - - // extra operations : - case this.tok.T_COALESCE: - // $username = $_GET['user'] ?? 'nobody'; - return this.node('coalesce')( - expr, this.next().read_expr() - ); - - case '?': - var trueArg = null; - if (this.next().token !== ':') { - trueArg = this.read_expr(); - } - this.expect(':').next(); - return ['retif', expr, trueArg, this.read_expr()]; + // binary operations + if (this.token === '|') + return result('bin', '|', expr, this.next().read_expr()); + if (this.token === '&') + return result('bin', '&', expr, this.next().read_expr()); + if (this.token === '^') + return result('bin', '^', expr, this.next().read_expr()); + if (this.token === '.') + return result('bin', '.', expr, this.next().read_expr()); + if (this.token === '+') + return result('bin', '+', expr, this.next().read_expr()); + if (this.token === '-') + return result('bin', '-', expr, this.next().read_expr()); + if (this.token === '*') + return result('bin', '*', expr, this.next().read_expr()); + if (this.token === '/') + return result('bin', '/', expr, this.next().read_expr()); + if (this.token === '%') + return result('bin', '%', expr, this.next().read_expr()); + if (this.token === this.tok.T_POW) + return result('bin', '**', expr, this.next().read_expr()); + if (this.token === this.tok.T_SL) + return result('bin', '<<', expr, this.next().read_expr()); + if (this.token === this.tok.T_SR) + return result('bin', '>>', expr, this.next().read_expr()); + // boolean operations + if (this.token === this.tok.T_BOOLEAN_OR) + return result('bool', '|', expr, this.next().read_expr()); + if (this.token === this.tok.T_LOGICAL_OR) + return result('bool', '|', expr, this.next().read_expr()); + if (this.token === this.tok.T_BOOLEAN_AND) + return result('bool', '&', expr, this.next().read_expr()); + if (this.token === this.tok.T_LOGICAL_AND) + return result('bool', '&', expr, this.next().read_expr()); + if (this.token === this.tok.T_LOGICAL_XOR) + return result('bool', '^', expr, this.next().read_expr()); + if (this.token === this.tok.T_IS_IDENTICAL) + return result('bool', '=', expr, this.next().read_expr()); + if (this.token === this.tok.T_IS_NOT_IDENTICAL) + return result('bool', '!=', expr, this.next().read_expr()); + if (this.token === this.tok.T_IS_EQUAL) + return result('bool', '~', expr, this.next().read_expr()); + if (this.token === this.tok.T_IS_NOT_EQUAL) + return result('bool', '!~', expr, this.next().read_expr()); + if (this.token === '<') + return result('bool', '<', expr, this.next().read_expr()); + if (this.token === '>') + return result('bool', '!~', expr, this.next().read_expr()); + if (this.token === this.tok.T_IS_SMALLER_OR_EQUAL) + return result('bool', '<=', expr, this.next().read_expr()); + if (this.token === this.tok.T_IS_GREATER_OR_EQUAL) + return result('bool', '=>', expr, this.next().read_expr()); + if (this.token === this.tok.T_SPACESHIP) + return result('bool', '<=>', expr, this.next().read_expr()); + if (this.token === this.tok.T_INSTANCEOF) + return result('bool', '?', expr, this.next().read_expr()); + + // extra operations : + // $username = $_GET['user'] ?? 'nobody'; + if (this.token === this.tok.T_COALESCE) + return result('coalesce', expr, this.next().read_expr()); + + // extra operations : + // $username = $_GET['user'] ? true : false; + if (this.token === '?') { + var trueArg = null; + if (this.next().token !== ':') { + trueArg = this.read_expr(); + } + this.expect(':') && this.next(); + return result('retif', expr, trueArg, this.read_expr()); } + return expr; } @@ -69,114 +94,143 @@ module.exports = { */ ,read_expr_item: function() { - switch(this.token) { - - case '@': - return ['silent', this.next().read_expr()]; - - case '-': - var result = this.node(); + if (this.token === '@') + return this.node('silent')(this.next().read_expr()); + if (this.token === '+') + return this.node('unary')('+', this.next().read_expr()); + if (this.token === '!') + return this.node('unary')('!', this.next().read_expr()); + if (this.token === '~') + return this.node('unary')('~', this.next().read_expr()); + + if (this.token === '-') { + var result = this.node(); + this.next(); + if ( + this.token === this.tok.T_LNUMBER || + this.token === this.tok.T_DNUMBER + ) { + // negative number + result = result('number', '-' + this.text()); this.next(); - if ( - this.token === this.tok.T_LNUMBER || - this.token === this.tok.T_DNUMBER - ) { - // negative number - result = result('number', '-' + this.text()); - this.next(); - return result; - } else { - return result('unary', '-', this.read_expr()); - } - - case '+': - case '!': - case '~': - return this.node('unary')(this.token, this.read_expr()); - - case '(': - var expr = this.next().read_expr(); - this.expect(')').next(); + return result; + } else { + return result('unary', '-', this.read_expr()); + } + } - // handle dereferencable - if (this.token === this.tok.T_OBJECT_OPERATOR) { - return this.recursive_variable_chain_scan(expr, false); - } else if (this.token === this.tok.T_CURLY_OPEN || this.token === '[') { - return this.read_dereferencable(expr); - } else if (this.token === '(') { - // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1118 - return this.node('call')( - expr, this.read_function_argument_list() - ); - } else { - return expr; - } + if (this.token === '(') { + var expr = this.next().read_expr(); + this.expect(')') && this.next(); + // handle dereferencable + if (this.token === this.tok.T_OBJECT_OPERATOR) { + return this.recursive_variable_chain_scan(expr, false); + } else if (this.token === this.tok.T_CURLY_OPEN || this.token === '[') { + return this.read_dereferencable(expr); + } else if (this.token === '(') { + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1118 + return this.node('call')( + expr, this.read_function_argument_list() + ); + } else { + return expr; + } + } - case '`': - // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1048 - var result = this.node('shell'); - var expr = this.next().read_encapsed_string('`'); - return result(expr); + if (this.token === '`') { + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1048 + return this.node('shell')( + this.next().read_encapsed_string('`') + ); + } - case this.tok.T_LIST: - var result = this.node('list'); - this.next().expect('(').next(); - var isInner = this.innerList; + if (this.token === this.tok.T_LIST) { + var result = this.node('list'), assign = null; + var isInner = this.innerList; + if (!isInner) { + assign = this.node('assign'); + } + if (this.next().expect('(')) { + this.next(); + } - if (!this.innerList) this.innerList = true; - var assignList = this.read_assignment_list(); + if (!this.innerList) this.innerList = true; + var assignList = this.read_assignment_list(); - // check if contains at least one assignment statement - var hasItem = false; - for(var i = 0; i < assignList.length; i++) { - if (assignList[i] !== null) { - hasItem = true; - break; - } - } - if (!hasItem) { - this.raiseError( - 'Fatal Error : Cannot use empty list on line ' + this.lexer.yylloc.first_line - ); + // check if contains at least one assignment statement + var hasItem = false; + for(var i = 0; i < assignList.length; i++) { + if (assignList[i] !== null) { + hasItem = true; + break; } - this.expect(')').next(); + } + if (!hasItem) { + this.raiseError( + 'Fatal Error : Cannot use empty list on line ' + this.lexer.yylloc.first_line + ); + } + if (this.expect(')')) { + this.next(); + } - if (!isInner) { - this.innerList = false; - this.expect('=').next(); - return result(assignList, this.read_expr()); + if (!isInner) { + this.innerList = false; + if (this.expect('=')) { + return assign( + result(assignList), + this.next().read_expr(), + '=' + ); } else { - return result(assignList, null); + // fallback : list($a, $b); + return result(assignList); } + } else { + return result(assignList); + } + } - case this.tok.T_CLONE: - return this.node('clone')( - this.next().read_expr() - ); + if (this.token === this.tok.T_CLONE) + return this.node('clone')( + this.next().read_expr() + ); + + switch(this.token) { case this.tok.T_INC: - var name = this.next().read_variable(false, false, false); - return ['set', name, ['bin', '+', name, ['number', 1]]]; + return this.node('pre')( + '+', this.next().read_variable(false, false, false) + ); case this.tok.T_DEC: - var name = this.next().read_variable(false, false, false); - return ['set', name, ['bin', '-', name, ['number', 1]]]; + return this.node('pre')( + '-', this.next().read_variable(false, false, false) + ); case this.tok.T_NEW: return this.next().read_new_expr(); case this.tok.T_ISSET: var result = this.node('isset'); - this.next().expect('(').next(); + if (this.next().expect('(')) { + this.next(); + } var args = this.read_list(this.read_expr, ','); - this.expect(')').next(); + if (this.expect(')')) { + this.next(); + } return result(args); case this.tok.T_EMPTY: var result = this.node('empty'); - this.next().expect('(').next(); + if (this.next().expect('(')) { + this.next(); + } var arg = this.read_expr(); - this.expect(')').next(); + if (this.expect(')')) { + this.next(); + } return result([arg]); case this.tok.T_INCLUDE: @@ -205,28 +259,32 @@ module.exports = { case this.tok.T_EVAL: var result = this.node('eval'); - this.next().expect('(').next(); + if (this.next().expect('(')) { + this.next(); + } var expr = this.read_expr(); - this.expect(')').next(); + if (this.expect(')')) { + this.next(); + } return result(expr); case this.tok.T_INT_CAST: - return ['cast', 'int', this.next().read_expr()]; + return this.node('cast')('int', this.next().read_expr()); case this.tok.T_DOUBLE_CAST: - return ['cast', 'double', this.next().read_expr()]; + return this.node('cast')('double', this.next().read_expr()); case this.tok.T_STRING_CAST: - return ['cast', 'string', this.next().read_expr()]; + return this.node('cast')('string', this.next().read_expr()); case this.tok.T_ARRAY_CAST: - return ['cast', 'array', this.next().read_expr()]; + return this.node('cast')('array', this.next().read_expr()); case this.tok.T_OBJECT_CAST: - return ['cast', 'object', this.next().read_expr()]; + return this.node('cast')('object', this.next().read_expr()); case this.tok.T_BOOL_CAST: - return ['cast', 'boolean', this.next().read_expr()]; + return this.node('cast')('boolean', this.next().read_expr()); case this.tok.T_UNSET_CAST: return this.node('unset')( @@ -239,7 +297,9 @@ module.exports = { if ( this.next().token === '(' ) { if (this.next().token !== ')') { status = this.read_expr(); - this.expect(')').next(); + if (this.expect(')')) { + this.next(); + } } else { this.next(); } @@ -277,11 +337,11 @@ module.exports = { // SCALAR | VARIABLE var expr; if (this.is('VARIABLE')) { + var result = this.node(); expr = this.read_variable(false, false, false); // VARIABLES SPECIFIC OPERATIONS switch(this.token) { case '=': - var result = this.node('assign'); var right; if (this.next().token == '&') { if (this.next().token === this.tok.T_NEW) { @@ -292,40 +352,51 @@ module.exports = { } else { right = this.read_expr(); } - return result(expr, right, '='); + return result('assign', expr, right, '='); // operations : case this.tok.T_PLUS_EQUAL: - return ['set', expr, ['bin', '+', expr, this.next().read_expr()]]; + return result('assign', expr, this.next().read_expr(), '+='); + case this.tok.T_MINUS_EQUAL: - return ['set', expr, ['bin', '-', expr, this.next().read_expr()]]; + return result('assign', expr, this.next().read_expr(), '-='); + case this.tok.T_MUL_EQUAL: - return ['set', expr, ['bin', '*', expr, this.next().read_expr()]]; + return result('assign', expr, this.next().read_expr(), '*='); + case this.tok.T_POW_EQUAL: - return ['set', expr, ['bin', '**', expr, this.next().read_expr()]]; + return result('assign', expr, this.next().read_expr(), '**='); + case this.tok.T_DIV_EQUAL: - return ['set', expr, ['bin', '/', expr, this.next().read_expr()]]; + return result('assign', expr, this.next().read_expr(), '/='); + case this.tok.T_CONCAT_EQUAL: - // NB : convert as string and add - return ['set', expr, ['bin', '.', expr, this.next().read_expr()]]; + return result('assign', expr, this.next().read_expr(), '.='); + case this.tok.T_MOD_EQUAL: - return ['set', expr, ['bin', '%', expr, this.next().read_expr()]]; + return result('assign', expr, this.next().read_expr(), '%='); + case this.tok.T_AND_EQUAL: - return ['set', expr, ['bin', '&', expr, this.next().read_expr()]]; + return result('assign', expr, this.next().read_expr(), '&='); + case this.tok.T_OR_EQUAL: - return ['set', expr, ['bin', '|', expr, this.next().read_expr()]]; + return result('assign', expr, this.next().read_expr(), '|='); + case this.tok.T_XOR_EQUAL: - return ['set', expr, ['bin', '^', expr, this.next().read_expr()]]; + return result('assign', expr, this.next().read_expr(), '^='); + case this.tok.T_SL_EQUAL: - return ['set', expr, ['bin', '<<', expr, this.next().read_expr()]]; + return result('assign', expr, this.next().read_expr(), '<<='); + case this.tok.T_SR_EQUAL: - return ['set', expr, ['bin', '>>', expr, this.next().read_expr()]]; + return result('assign',expr, this.next().read_expr(), '>>='); + case this.tok.T_INC: this.next(); - return ['post', '+', expr]; + return result('post', '+', expr); case this.tok.T_DEC: this.next(); - return ['post', '-', expr]; + return result('post', '-', expr); } } else if (this.is('SCALAR')) { expr = this.read_scalar(); @@ -343,7 +414,7 @@ module.exports = { } } } else { - expr = this.error('EXPR'); + this.error('EXPR'); this.next(); } @@ -360,22 +431,26 @@ module.exports = { ,read_new_expr: function() { var result = this.node('new'); if (this.token === this.tok.T_CLASS) { + var what = this.node('class'); // Annonymous class declaration - var propExtends = false, propImplements = false; + var propExtends = null, propImplements = null, body = null; if (this.next().token == this.tok.T_EXTENDS) { propExtends = this.next().read_namespace_name(); } if (this.token == this.tok.T_IMPLEMENTS) { - propImplements = this.next().read_list( - this.read_namespace_name, - ',' - ); + propImplements = this.next().read_name_list(); + } + if (this.expect('{')) { + body = this.next().read_class_body(); } return result( - false // class name => false : means it's an annonymous class - ,propExtends - ,propImplements - ,this.expect('{').next().read_class_body() + what( + null + ,propExtends + ,propImplements + ,body + ,[0, 0, 0] + ), [] ); } else { // Already existing class @@ -398,8 +473,6 @@ module.exports = { var result = this.read_namespace_name(); if (this.token === this.tok.T_DOUBLE_COLON) { result = this.read_static_getter(result); - } else { - result = ['ns', result]; } return result; } else if (this.is('VARIABLE')) { diff --git a/src/parser/function.js b/src/parser/function.js index 50af5f964..1e6bc44e2 100644 --- a/src/parser/function.js +++ b/src/parser/function.js @@ -32,12 +32,19 @@ module.exports = { * ``` */ ,read_function: function(closure, flag) { - var result = this.read_function_declaration(closure ? 1 : flag ? 2 : 0) + var result = this.read_function_declaration( + closure ? 1 : (flag ? 2 : 0) + ); if (flag && flag[2] == 1) { + // abstract function : result.parseFlags(flag); - this.expect(';').nextWithComments(); + if (this.expect(';')) { + this.nextWithComments(); + } } else { - result.children = this.expect('{').read_code_block(false); + if (this.expect('{')) { + result.body = this.read_code_block(false); + } if (flag) { result.parseFlags(flag); } @@ -58,27 +65,37 @@ module.exports = { nodeName = 'method'; } var result = this.node(nodeName); - this.expect(this.tok.T_FUNCTION); - var isRef = this.next().is_reference(); - var name = false, use = [], returnType = false; - if (type !== 1) { - name = this.expect(this.tok.T_STRING).text(); + if (this.expect(this.tok.T_FUNCTION)) { this.next(); } - this.expect('(').next(); + var isRef = this.is_reference(); + var name = false, use = [], returnType = null, nullable = false; + if (type !== 1) { + if (this.expect(this.tok.T_STRING)) { + name = this.text(); + this.next(); + } + } + if (this.expect('(')) this.next(); var params = this.read_parameter_list(); - this.expect(')').next(); + if (this.expect(')')) this.next(); if (type === 1 && this.token === this.tok.T_USE) { - use = this.next().expect('(').next().read_list(this.read_lexical_var, ','); - this.expect(')').next(); + if (this.next().expect('(')) this.next(); + use = this.read_list(this.read_lexical_var, ','); + if (this.expect(')')) this.next(); } if (this.token === ':') { - returnType = this.next().read_type(); + if (this.next().token === '?') { + nullable = true; + this.next(); + } + returnType = this.read_type(); } if (type === 1) { - return result(params, isRef, use, returnType); + // closure + return result(params, isRef, use, returnType, nullable); } - return result(name, params, isRef, returnType); + return result(name, params, isRef, returnType, nullable); } /** * ```ebnf @@ -129,25 +146,39 @@ module.exports = { * @see https://github.com/php/php-src/blob/493524454d66adde84e00d249d607ecd540de99f/Zend/zend_language_parser.y#L640 */ ,read_parameter: function() { - var node = this.node('parameter'); - var type = this.read_type(); + var node = this.node('parameter'), + name = null, + value = null, + type = null, + nullable = false; + if (this.token === '?') { + this.next(); + nullable = true; + } + type = this.read_type(); + if (nullable && !type) { + this.raiseError('Expecting a type definition combined with nullable operator'); + } var isRef = this.is_reference(); var isVariadic = this.is_variadic(); - var name = this.expect(this.tok.T_VARIABLE).text(); - var value = null; - if (this.next().token == '=') { + if (this.expect(this.tok.T_VARIABLE)) { + name = this.text(); + this.next(); + } + if (this.token == '=') { value = this.next().read_expr(); } - return node(name, type, value, isRef, isVariadic); + return node(name, type, value, isRef, isVariadic, nullable); } /** + * Reads a list of arguments * ```ebnf * function_argument_list ::= '(' (argument_list (',' argument_list)*)? ')' * ``` */ ,read_function_argument_list: function() { var result = []; - this.expect('(').next(); + this.expect('(') && this.next(); if (this.token !== ')') { while(this.token != this.EOF) { result.push(this.read_argument_list()); @@ -156,7 +187,7 @@ module.exports = { } else break; } } - this.expect(')').next(); + this.expect(')') && this.next(); return result; } /** @@ -177,16 +208,18 @@ module.exports = { * ``` */ ,read_type: function() { + var result = this.node('identifier'); switch(this.token) { case this.tok.T_ARRAY: this.next(); - return ['array']; + return result(['', 'array'], false); + case this.tok.T_NAMESPACE: case this.tok.T_NS_SEPARATOR: case this.tok.T_STRING: return this.read_namespace_name(); case this.tok.T_CALLABLE: this.next(); - return ['callable']; + return result(['', 'callable'], false); default: return null; } diff --git a/src/parser/if.js b/src/parser/if.js index da231e630..e37edee95 100644 --- a/src/parser/if.js +++ b/src/parser/if.js @@ -6,83 +6,93 @@ module.exports = { /** + * Reads an IF statement + * * ```ebnf * if ::= '(' expr ')' ':' ... * ``` */ read_if: function() { - var result = this.node('if'); - var cond = this.read_if_expr(); - var body = null; - var elseCond = false; + var result = this.node('if'), + body = null, + alternate = null, + shortForm = false, + test = null; + test = this.read_if_expr(); if (this.token === ':') { + shortForm = true; this.next(); - body = []; + body = this.node('block'); + var items = []; while(this.token != this.EOF && this.token !== this.tok.T_ENDIF) { this.ignoreComments(); if (this.token === this.tok.T_ELSEIF) { - elseCond = this.next().read_elseif_short(); + alternate = this.next().read_elseif_short(); break; } else if (this.token === this.tok.T_ELSE) { - elseCond = this.next().read_else_short(); + alternate = this.next().read_else_short(); break; } - body.push(this.read_inner_statement()); + items.push(this.read_inner_statement()); } - this.ignoreComments().expect(this.tok.T_ENDIF).next().expectEndOfStatement(); + body = body(null, items); + if (this.ignoreComments().expect(this.tok.T_ENDIF)) this.next(); + this.expectEndOfStatement(); } else { body = this.read_statement(); this.ignoreComments(); if (this.token === this.tok.T_ELSEIF) { - elseCond = this.next().read_if(); + alternate = this.next().read_if(); } else if (this.token === this.tok.T_ELSE) { - elseCond = this.next().read_statement(); + alternate = this.next().read_statement(); } } - return result(cond, body, elseCond); + return result(test, body, alternate, shortForm); }, /** * reads an if expression : '(' expr ')' */ read_if_expr: function() { - this.expect('(').next(); + if (this.expect('(')) this.next(); var result = this.read_expr(); - this.expect(')').next(); + if (this.expect(')')) this.next(); return result; }, /** * reads an elseif (expr): statements */ read_elseif_short: function() { - var result = this.node('if'); - var cond = this.read_if_expr(); - this.expect(':').next(); - var body = []; - var elseCond = false; - + var result = this.node('if'), + alternate = null, + test = null, + body = null, + items = []; + test = this.read_if_expr(); + if (this.expect(':')) this.next(); + body = this.node('block'); while(this.token != this.EOF && this.token !== this.tok.T_ENDIF) { if (this.token === this.tok.T_ELSEIF) { - elseCond = this.next().read_elseif_short(); + alternate = this.next().read_elseif_short(); break; } else if (this.token === this.tok.T_ELSE) { - elseCond = this.next().read_else_short(); + alternate = this.next().read_else_short(); break; } - body.push(this.read_inner_statement()); + items.push(this.read_inner_statement()); } - - return result(cond, body, elseCond); + body = body(null, items); + return result(test, body, alternate, true); }, /** * */ read_else_short: function() { - this.expect(':').next(); - var body = []; + if (this.expect(':')) this.next(); + var body = this.node('block'), items = []; while(this.token != this.EOF && this.token !== this.tok.T_ENDIF) { - body.push(this.read_inner_statement()); + items.push(this.read_inner_statement()); } - return body; + return body(null, items); } }; diff --git a/src/parser/loops.js b/src/parser/loops.js index 4f3e28277..288444c90 100644 --- a/src/parser/loops.js +++ b/src/parser/loops.js @@ -3,113 +3,154 @@ * @authors https://github.com/glayzzle/php-parser/graphs/contributors * @url http://glayzzle.com */ - +"use strict"; module.exports = { - /** - * Reads a short form of tokens - */ - read_short_form: function(token) { - var body = []; - this.expect(':').next(); - while(this.token != this.EOF && this.token !== token) { - body.push(this.read_inner_statement()); - } - this.expect(token).next().expectEndOfStatement(); - return body; - } /** * Reads a while statement + * ```ebnf + * while ::= T_WHILE (statement | ':' inner_statement_list T_ENDWHILE ';') + * ``` + * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L587 + * @return {While} */ - ,read_while: function() { - var result = this.node('while'); - this.expect('(').next(); - var cond = this.read_expr(); - this.expect(')').next(); - var body = []; + read_while: function() { + var result = this.node('while'), + test = null, + body = null, + shortForm = false + ; + if (this.expect('(')) this.next(); + test = this.read_expr(); + if (this.expect(')')) this.next(); if (this.token === ':') { + shortForm = true; body = this.read_short_form(this.tok.T_ENDWHILE); } else { body = this.read_statement(); } - return result(cond, body); + return result(test, body, shortForm); } + /** + * Reads a do / while loop + * ```ebnf + * do ::= T_DO statement T_WHILE '(' expr ')' ';' + * ``` + * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L423 + * @return {Do} + */ ,read_do: function() { - var result = this.node('do'); - var body = this.read_statement(); - this.expect(this.tok.T_WHILE).next().expect('(').next(); - var cond = this.read_expr(); - this.expect(')').next().expect(';').next(); - return result(cond, body); + var result = this.node('do'), + test = null, + body = null + ; + body = this.read_statement(); + if (this.expect(this.tok.T_WHILE)) { + if (this.next().expect('(')) this.next(); + test = this.read_expr(); + if (this.expect(')')) this.next(); + if (this.expect(';')) this.next(); + } + return result(test, body); } + /** + * Read a for incremental loop + * ```ebnf + * for ::= T_FOR '(' for_exprs ';' for_exprs ';' for_exprs ')' for_statement + * for_statement ::= statement | ':' inner_statement_list T_ENDFOR ';' + * for_exprs ::= expr? (',' expr)* + * ``` + * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L425 + * @return {For} + */ ,read_for: function() { - var result = this.node('for'); - this.expect('(').next(); - var expr1 = null, expr2 = null, expr3 = null; + var result = this.node('for'), + init = [], + test = [], + increment = [], + body = null, + shortForm = false; + if (this.expect('(')) this.next(); if (this.token !== ';') { - expr1 = this.read_list(this.read_expr, ','); - this.expect(';').next(); + init = this.read_list(this.read_expr, ','); + if (this.expect(';')) this.next(); } else { this.next(); } if (this.token !== ';') { - expr2 = this.read_list(this.read_expr, ','); - this.expect(';').next(); + test = this.read_list(this.read_expr, ','); + if (this.expect(';')) this.next(); } else { this.next(); } if (this.token !== ')') { - expr3 = this.read_list(this.read_expr, ','); - this.expect(')').next(); + increment = this.read_list(this.read_expr, ','); + if (this.expect(')')) this.next(); } else { this.next(); } - var body = null; if (this.token === ':') { + shortForm = true; body = this.read_short_form(this.tok.T_ENDFOR); } else { body = this.read_statement(); } - return result(expr1, expr2, expr3, body); + return result(init, test, increment, body, shortForm); } /** + * Reads a foreach loop * ```ebnf * foreach ::= '(' expr T_AS foreach_variable (T_DOUBLE_ARROW foreach_variable)? ')' statement * ``` + * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L438 + * @return {Foreach} */ ,read_foreach: function() { - var result = this.node('foreach'); - this.expect('(').next(); - var expr = this.read_expr(); - this.expect(this.tok.T_AS).next(); - var item = this.read_foreach_variable(), - key = false; - if (this.token === this.tok.T_DOUBLE_ARROW) { - key = item; - item = this.next().read_foreach_variable(); + var result = this.node('foreach'), + source = null, + key = null, + value = null, + body = null, + shortForm = false; + if (this.expect('(')) this.next(); + source = this.read_expr(); + if (this.expect(this.tok.T_AS)) { + this.next(); + value = this.read_foreach_variable(); + if (this.token === this.tok.T_DOUBLE_ARROW) { + key = value; + value = this.next().read_foreach_variable(); + } } - this.expect(')').next(); - var body = []; + + if (this.expect(')')) this.next(); + if (this.token === ':') { + shortForm = true; body = this.read_short_form(this.tok.T_ENDFOREACH); } else { body = this.read_statement(); } - return result(expr, key, item, body); + return result(source, key, value, body, shortForm); } /** + * Reads a foreach variable statement * ```ebnf - * foreach_variable = ('&'? variable) | (T_LIST '(' assignment_list ')') + * foreach_variable = variable | + * T_LIST '(' assignment_list ')' | + * '[' array_pair_list ']' * ``` + * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L544 + * @return {Expression} */ ,read_foreach_variable: function() { - if (this.token === '&') { - return this.next().read_variable(false, false, true); - } else if (this.token === this.tok.T_LIST) { + if (this.token === this.tok.T_LIST) { var result = this.node('list'); - this.next().expect('(').next(); + if (this.next().expect('(')) this.next(); var assignList = this.read_assignment_list(); - this.expect(')').next(); - return result(assignList, false); + if (this.expect(')')) this.next(); + return result(assignList); + } else if (this.token === '[') { + return this.read_array(); } else { return this.read_variable(false, false, false); } diff --git a/src/parser/namespace.js b/src/parser/namespace.js index 77c76b91f..c8ae8f4af 100644 --- a/src/parser/namespace.js +++ b/src/parser/namespace.js @@ -3,27 +3,27 @@ * @authors https://github.com/glayzzle/php-parser/graphs/contributors * @url http://glayzzle.com */ +"use strict"; module.exports = { /** + * Reads a namespace declaration block * ```ebnf * namespace ::= T_NAMESPACE namespace_name? '{' * top_statements * '}' * | T_NAMESPACE namespace_name ';' top_statements * ``` + * @see http://php.net/manual/en/language.namespaces.php + * @return {Namespace} */ read_namespace: function() { - this.expect(this.tok.T_NAMESPACE).next(); var result = this.node('namespace'); + this.expect(this.tok.T_NAMESPACE) && this.next(); if (this.token == '{') { this.currentNamespace = ['']; - return result([''], this.read_code_block(true)); + return result([''], this.read_code_block(true), true); } else { - if(this.token === this.tok.T_NAMESPACE) { - this.error(['{', this.tok.T_STRING]); - this.next(); // ignore namespace token - } var name = this.read_namespace_name(); if (this.token == ';') { this.currentNamespace = name; @@ -32,12 +32,13 @@ module.exports = { return result(name, body); } else if (this.token == '{') { this.currentNamespace = name; - return result(name, this.read_code_block(true)); + return result(name, this.read_code_block(true), true); } else if (this.token === '(') { // resolve ambuiguity between namespace & function call + name.resolution = this.ast.identifier.RELATIVE_NAME; + name.name = name.name.substring(1); return this.node('call')( - ['ns', name.slice(1)] - , this.read_function_argument_list() + name, this.read_function_argument_list() ); } else { this.error(['{', ';']); @@ -50,108 +51,118 @@ module.exports = { } } /** - * reading a namespace name + * Reads a namespace name * ```ebnf * namespace_name ::= T_NS_SEPARATOR? (T_STRING T_NS_SEPARATOR)* T_STRING * ``` + * @see http://php.net/manual/en/language.namespaces.rules.php + * @return {Identifier} */ ,read_namespace_name: function() { - var result = this.node('identifier'); + var result = this.node('identifier'), relative = false; if (this.token === this.tok.T_NAMESPACE) { - this.next().expect(this.tok.T_NS_SEPARATOR).next(); + this.next().expect(this.tok.T_NS_SEPARATOR) && this.next(); + relative = true } return result( - this.read_list(this.tok.T_STRING, this.tok.T_NS_SEPARATOR, true) + this.read_list(this.tok.T_STRING, this.tok.T_NS_SEPARATOR, true), + relative ); } /** + * Reads a use statement * ```ebnf - * use_statements ::= - * use_statements ',' use_statement - * | use_statement + * use_statement ::= T_USE + * use_type? use_declarations | + * use_type use_statement '{' use_declarations '}' | + * use_statement '{' use_declarations(=>typed) '}' + * ';' * ``` + * @see http://php.net/manual/en/language.namespaces.importing.php + * @return {UseGroup} */ - ,read_use_statements: function() { - var result = []; - while(this.token !== this.EOF) { - this.expect(this.tok.T_USE).next(); - this.read_list(this.read_use_statement_mixed, ',').forEach(function(item) { - if (Array.isArray(item)) { - result = result.concat(item); - } else { - result.push(item); - } - }); - if(this.token !== this.tok.T_USE) break; - } - return result; + ,read_use_statement: function() { + var result = this.node('usegroup'), + type = null, + items = [], + name = null + ; + this.expect(this.tok.T_USE) && this.next(); + type = this.read_use_type(); + items.push(this.read_use_declaration(false)); + if (this.token === ',') { + items = items.concat(this.next().read_use_declarations(false)); + } else if (this.token === '{') { + name = items[0].name; + items = this.next().read_use_declarations(type === null); + this.expect('}') && this.next(); + } + this.expect(';') && this.nextWithComments(); + return result(name, type, items); } /** + * Reads a use declaration * ```ebnf - * inline_use_declaration ::= ... + * use_declaration ::= use_type? namespace_name use_alias * ``` - * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L375 + * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L380 + * @return {UseItem} */ - ,read_inline_use_declaration: function(prefix) { - var result = []; - while(this.token !== this.EOF) { - var node = this.node('use'); - var ns = this.read_use_statement(prefix[3] !== false); - if(this.token === this.tok.T_AS) { - this.next().expect(this.tok.T_STRING); - ns[1] = this.text(); - this.next(); - } - ns[0] = prefix[0].concat(ns[0]); - if (prefix[2] !== false) { - ns[2] = prefix[2]; - } - result.push(node.apply(this, ns)); - if(this.token !== ',') { - break; - } else { - this.next(); - } + ,read_use_declaration: function(typed) { + var result = this.node('useitem'), type = null; + if (typed) type = this.read_use_type(); + var name = this.read_namespace_name(); + var alias = this.read_use_alias(); + return result(name, alias, type); + } + /** + * Reads a list of use declarations + * ```ebnf + * use_declarations ::= use_declaration (',' use_declaration)* + * ``` + * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L380 + * @return {UseItem[]} + */ + ,read_use_declarations: function(typed) { + var result = [this.read_use_declaration(typed)]; + while(this.token === ',') { + result.push(this.next().read_use_declaration(typed)); } return result; } /** + * Reads a use statement * ```ebnf - * use_statement_mixed ::= - * use_statement (T_AS T_STRING | '{' read_inline_use_declaration '}' ) - * (',' read_use_statement)* + * use_alias ::= (T_AS T_STRING)? * ``` + * @return {String|null} */ - ,read_use_statement_mixed: function() { - var result = this.node('use'); - var use = this.read_use_statement(); - if(this.token === this.tok.T_AS) { - this.next().expect(this.tok.T_STRING); - use[1] = this.text(); - this.next(); - } else if (this.token === '{') { - use = this.next().read_inline_use_declaration(use); - this.expect('}').next(); - return use; + ,read_use_alias: function() { + var result = null; + if (this.token === this.tok.T_AS) { + if (this.next().expect(this.tok.T_STRING)) { + result = this.text(); + this.next(); + } } - return result.apply(this, use); + return result; } /** + * Reads the namespace type declaration * ```ebnf - * use_statement ::= ( - * (T_FUNCTION | T_CONST)? namespace_name - * ) + * use_type ::= (T_FUNCTION | T_CONST)? * ``` + * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L335 + * @return {String|null} Possible values : function, const */ - ,read_use_statement: function(ignoreType) { - var type = false; - if( - !ignoreType && (this.token === this.tok.T_FUNCTION || this.token === this.tok.T_CONST) - ) { - type = this.token === this.tok.T_FUNCTION ? 'function' : 'constant'; - this.next(); - } - var name = this.read_namespace_name(); - return [name, name[name.length - 1], type]; + ,read_use_type: function() { + if (this.token === this.tok.T_FUNCTION) { + this.next(); + return this.ast.useitem.TYPE_FUNCTION; + } else if (this.token === this.tok.T_CONST) { + this.next(); + return this.ast.useitem.TYPE_CONST; + } + return null; } }; diff --git a/src/parser/scalar.js b/src/parser/scalar.js index e1b55c927..400883bb5 100644 --- a/src/parser/scalar.js +++ b/src/parser/scalar.js @@ -58,11 +58,11 @@ module.exports = { isDoubleQuote = text[0] === '"'; text = text.substring(1, text.length - 1); } + this.next(); value = value(isDoubleQuote, this.resolve_special_chars(text)); if (isBinCast) { value = ['cast', 'binary', value]; } - this.next(); if (this.token === this.tok.T_DOUBLE_COLON) { // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1151 return this.read_static_getter(value); @@ -87,9 +87,7 @@ module.exports = { var result = this.node('number'); var value = this.text(); if (this.token === '-') { - this.next().expect([ - this.tok.T_LNUMBER, this.tok.T_DNUMBER - ]); + this.next().expect([this.tok.T_LNUMBER, this.tok.T_DNUMBER]); value += this.text(); } result = result(value); @@ -104,14 +102,17 @@ module.exports = { var result = ['constant', value]; if ( this.token == this.tok.T_DOUBLE_COLON) { // class constant MyClass::CONSTANT - this.next().expect([this.tok.T_STRING, this.tok.T_CLASS]); - result[1] = [value, this.text()]; - this.next(); + if (this.next().expect([this.tok.T_STRING, this.tok.T_CLASS])) { + result[1] = [value, this.text()]; + this.next(); + } } // CONSTANT ARRAYS OFFSET : MYCONST[1][0]... while(this.token === '[') { - result = ['offset', result, this.next().read_expr()]; - this.expect(']').next(); + var node = this.node('offsetlookup'); + var offset = this.next().read_expr(); + if (this.expect(']')) this.next(); + result = node(result, offset); } return result; @@ -132,11 +133,14 @@ module.exports = { */ ,read_dereferencable: function(expr) { var result; + var node = this.node('offsetlookup'); if (this.token === '[') { - result = ['offset', expr, this.next().read_expr()]; - this.expect(']').next(); + var offset = this.next().read_expr(); + if (this.expect(']')) this.next(); + result = node(expr, offset); } else if (this.token === this.tok.T_DOLLAR_OPEN_CURLY_BRACES) { - result = ['offset', expr, this.read_encapsed_string_item()]; + var offset = this.read_encapsed_string_item(); + result = node(expr, offset); } return result; } @@ -159,19 +163,23 @@ module.exports = { if (this.next().token === this.tok.T_STRING_VARNAME) { result = ['var', this.text()]; if (this.next().token === '[') { - result = ['offset', result, this.next().read_expr()]; - this.expect(']').next(); + var node = this.node('offsetlookup'); + var offset = this.next().read_expr(); + if (this.expect(']')) this.next(); + result = node(result, offset); } } else { result = this.read_expr(); } - this.expect('}').next(); + if (this.expect('}')) this.next(); } else if (this.token === this.tok.T_CURLY_OPEN) { result = this.next().read_variable(false, false, false); - this.expect('}').next(); + if (this.expect('}')) this.next(); } else if (this.token === '[') { - result = ['offset', result, this.next().read_expr()]; - this.expect(']').next(); + var node = this.node('offsetlookup'); + var offset = this.next().read_expr(); + if (this.expect(']')) this.next(); + result = node(result, offset); } else if (this.token === this.tok.T_VARIABLE) { result = this.read_variable(false, true, false); } else { @@ -180,7 +188,7 @@ module.exports = { this.tok.T_CURLY_OPEN, this.tok.T_DOLLAR_OPEN_CURLY_BRACES, this.tok.T_ENCAPSED_AND_WHITESPACE - ]) + ]); } return result; } @@ -202,12 +210,12 @@ module.exports = { , first , this.read_encapsed_string_item() ]; - while(this.token !== expect) { + while(this.token !== expect && this.token !== this.EOF) { result[3] = [ 'bin', '.', result[3], this.read_encapsed_string_item() ]; } - this.expect(expect).next(); + if (this.expect(expect)) this.next(); return result; } /** diff --git a/src/parser/statement.js b/src/parser/statement.js index 0a378a8b9..e1d0a93a3 100644 --- a/src/parser/statement.js +++ b/src/parser/statement.js @@ -37,38 +37,35 @@ module.exports = { ,read_top_statement: function() { switch(this.token) { case this.tok.T_FUNCTION: - return this.read_function(); + return this.read_function(false, false); // optional flags case this.tok.T_ABSTRACT: case this.tok.T_FINAL: var flag = this.read_class_scope(); - switch(this.token) { - case this.tok.T_CLASS: - return this.read_class(flag); - case this.tok.T_INTERFACE: - return this.read_interface(flag); - default: - var err = this.error([this.tok.T_CLASS, this.tok.T_INTERFACE]); - this.next(); - return err; + if (this.token === this.tok.T_CLASS) { + return this.read_class(flag); + } else { + this.error(this.tok.T_CLASS); + this.next(); + return null; } case this.tok.T_CLASS: - return this.read_class(0); + return this.read_class([0, 0, 0]); case this.tok.T_INTERFACE: - return this.read_interface(0); + return this.read_interface(); case this.tok.T_TRAIT: return this.read_trait(); case this.tok.T_USE: - var expr = this.read_use_statements(); - this.expect(';').nextWithComments(); - return expr; + return this.read_use_statement(); case this.tok.T_CONST: return this.next().read_const_list(); case this.tok.T_NAMESPACE: return this.read_namespace(); case this.tok.T_HALT_COMPILER: var result = this.node('halt'); - this.next().expect('(').next().expect(')').next().expect(';'); + if (this.next().expect('(')) this.next(); + if (this.expect(')')) this.next(); + this.expect(';'); this.lexer.done = true; return result(this.lexer._input.substring( this.lexer.offset @@ -108,8 +105,12 @@ module.exports = { this.expect(this.tok.T_STRING); var result = this.node('constant'); var name = this.text(); - this.next().expect('=').next(); - return result(name, this.read_expr()); + if (this.next().expect('=')) { + return result(name, this.next().read_expr()); + } else { + // fallback + return result(name, null); + } }, ',', false); this.expectEndOfStatement(); return result; @@ -124,8 +125,11 @@ module.exports = { return this.read_list(function() { this.expect(this.tok.T_STRING); var name = this.text(); - this.next().expect('=').next(); - return [name, this.read_expr()]; + if (this.next().expect('=')) { + return [name, this.next().read_expr()]; + } else { + return [name, null]; + } }, ','); } /** @@ -137,30 +141,29 @@ module.exports = { ,read_inner_statement: function() { switch(this.token) { case this.tok.T_FUNCTION: - return this.read_function(); + return this.read_function(false, false); // optional flags case this.tok.T_ABSTRACT: case this.tok.T_FINAL: var flag = this.read_class_scope(); - switch(this.token) { - case this.tok.T_CLASS: - return this.read_class(flag); - case this.tok.T_INTERFACE: - return this.read_interface(flag); - default: - var err = this.error([this.tok.T_CLASS, this.tok.T_INTERFACE]); - // graceful mode : ignore token & go next - this.next(); - return err; + if (this.token === this.tok.T_CLASS) { + return this.read_class(flag); + } else { + this.error(this.tok.T_CLASS); + // graceful mode : ignore token & go next + this.next(); + return null; } case this.tok.T_CLASS: - return this.read_class(0); + return this.read_class([0, 0, 0]); case this.tok.T_INTERFACE: - return this.read_interface(0); + return this.read_interface(); case this.tok.T_TRAIT: return this.read_trait(); case this.tok.T_HALT_COMPILER: - this.next().expect('(').next().expect(')').next().expect(';').next(); + if (this.next().expect('(')) this.next(); + if (this.expect(')')) this.next(); + if (this.expect(';')) this.next(); this.raiseError('__HALT_COMPILER() can only be used from the outermost scope'); default: return this.read_statement(); @@ -192,25 +195,28 @@ module.exports = { case this.tok.T_DOC_COMMENT: return this.read_doc_comment(); case this.tok.T_RETURN: - case this.tok.T_BREAK: - case this.tok.T_CONTINUE: - var mode; - switch(this.token) { - case this.tok.T_RETURN: mode = 'return'; break; - case this.tok.T_BREAK: mode = 'break'; break; - case this.tok.T_CONTINUE: mode = 'continue'; break; - } - var expr = null; + var result = this.node('return'), expr = null; if (!this.next().is('EOS')) { expr = this.read_expr(); } this.expectEndOfStatement(); - return [mode, expr]; + return result(expr); + + case this.tok.T_BREAK: + var result = this.node('break'); + this.next().expectEndOfStatement(); + return result(); + + case this.tok.T_CONTINUE: + var result = this.node('continue'); + this.next().expectEndOfStatement(); + return result(); case this.tok.T_GLOBAL: + var result = this.node('global'); var items = this.next().read_list(this.read_simple_variable, ','); this.expectEndOfStatement(); - return ['global', items]; + return result(items); case this.tok.T_STATIC: var current = [this.token, this.lexer.getState()]; @@ -219,13 +225,16 @@ module.exports = { // static keyword for a class this.lexer.tokens.push(current); var expr = this.next().read_expr(); - this.expect(';').nextWithComments(); + this.expect(';') && this.nextWithComments(); return expr; } var items = this.read_list(function() { - var name = this.expect(this.tok.T_VARIABLE).text(); - var value = null; - if (this.next().token === '=') { + var value = null, name = null; + if (this.expect(this.tok.T_VARIABLE)) { + name = this.text(); + this.next(); + } + if (this.token === '=') { value = this.next().read_expr(); } return [name, value]; @@ -239,7 +248,7 @@ module.exports = { withParanthesis && this.next(); var args = this.read_list(this.read_expr, ','); if (withParanthesis) { - this.expect(')').next(); + this.expect(')') && this.next(); } this.expectEndOfStatement(); return result(args); @@ -251,28 +260,25 @@ module.exports = { case this.tok.T_UNSET: var result = this.node('unset'); - this.next().expect('(').next(); + this.next().expect('(') && this.next(); var items = this.read_list(this.read_variable, ','); - if (this.expect(')').next().expect(';')) { - result = result(items); - this.nextWithComments(); - } else { - result = result(items); - } - return result; + this.expect(')') && this.next(); + this.expect(';') && this.nextWithComments(); + return result(items); case this.tok.T_DECLARE: var result = this.node('declare'), options, body; - this.next().expect('(').next(); + this.next().expect('(') && this.next(); options = this.read_declare_list(); - this.expect(')').nextWithComments(); + this.expect(')') && this.nextWithComments(); if (this.token === ':') { body = []; this.next(); while(this.token != this.EOF && this.token !== this.tok.T_ENDDECLARE) { body.push(this.read_statement()); } - this.ignoreComments().expect(this.tok.T_ENDDECLARE).next().expectEndOfStatement(); + this.ignoreComments().expect(this.tok.T_ENDDECLARE) && this.next(); + this.expectEndOfStatement(); } else { body = this.read_statement(); } @@ -304,14 +310,16 @@ module.exports = { // default fallback expr this.lexer.tokens.push(current); var expr = this.next().read_expr(); - this.expect([';', this.tok.T_CLOSE_TAG]).nextWithComments(); + this.expect([';', this.tok.T_CLOSE_TAG]) && this.nextWithComments(); return expr; } case this.tok.T_GOTO: - var result = this.node('goto'); - var label = this.next().expect(this.tok.T_STRING).text(); - this.next().expectEndOfStatement(); + var result = this.node('goto'), label = null; + if (this.next().expect(this.tok.T_STRING)) { + label = this.text(); + this.next().expectEndOfStatement(); + } return result(label); default: // default fallback expr @@ -326,12 +334,13 @@ module.exports = { * ``` */ ,read_code_block: function(top) { - this.expect('{').nextWithComments(); + var result = this.node('block'); + this.expect('{') && this.nextWithComments(); var body = top ? this.read_top_statements() : this.read_inner_statements() ; - this.expect('}').nextWithComments(); - return body; + this.expect('}') && this.nextWithComments(); + return result(null, body); } }; diff --git a/src/parser/switch.js b/src/parser/switch.js index a1b65a617..afe98c905 100644 --- a/src/parser/switch.js +++ b/src/parser/switch.js @@ -3,30 +3,38 @@ * @authors https://github.com/glayzzle/php-parser/graphs/contributors * @url http://glayzzle.com */ +"use strict"; + module.exports = { /** * Reads a switch statement * ```ebnf * switch ::= T_SWITCH '(' expr ')' switch_case_list * ``` + * @return {Switch} + * @see http://php.net/manual/en/control-structures.switch.php */ read_switch: function() { - this.expect(this.tok.T_SWITCH).next(); - var result = this.node('switch'); - this.expect('(').next(); - var expr = this.read_expr(); - this.expect(')').next(); - var cases = this.read_switch_case_list(); - return result(expr, cases); + this.expect(this.tok.T_SWITCH) && this.next(); + var result = this.node('switch'), test, body, shortForm; + this.expect('(') && this.next(); + test = this.read_expr(); + this.expect(')') && this.next(); + shortForm = (this.token === ':'); + body = this.read_switch_case_list(); + return result(test, body, shortForm); } /** * ```ebnf * switch_case_list ::= '{' ';'? case_list* '}' | ':' ';'? case_list* T_ENDSWITCH ';' * ``` + * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L566 */ ,read_switch_case_list: function() { // DETECT SWITCH MODE - var expect = null, result = []; + var expect = null, + result = this.node('block'), + items = []; if (this.token === '{') { expect = '}'; } else if (this.token === ':') { @@ -35,9 +43,8 @@ module.exports = { this.expect(['{', ':']); } // OPTIONNAL ';' - this.next(); - if (this.token === ';') { - // why ? it's compliant with spec but why ... wtf ? + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L570 + if (this.next().token === ';') { this.next(); } // IGNORE THE CLOSE TAG TOKEN WITH SHORT MODE @@ -46,14 +53,14 @@ module.exports = { } // EXTRACTING CASES while(this.token !== this.EOF && this.token !== expect) { - result.push( this.read_case_list(expect) ); + items.push( this.read_case_list(expect) ); } // CHECK END TOKEN - this.expect(expect).next(); + this.expect(expect) && this.next(); if (expect === this.tok.T_ENDSWITCH) { this.expectEndOfStatement(); } - return result; + return result(null, items); } /** * ```ebnf @@ -61,27 +68,27 @@ module.exports = { * ``` */ ,read_case_list: function(stopToken) { - var result = { - condition: false, - body: [] - }; + var result = this.node('case'), test = null, body = null, items = []; if (this.token === this.tok.T_CASE) { - result.condition = this.next().read_expr(); + test = this.next().read_expr(); } else if (this.token === this.tok.T_DEFAULT) { // the defaut entry - no condition this.next(); } else { this.expect([this.tok.T_CASE, this.tok.T_DEFAULT]); } - this.expect([':', ';']).next(); + this.expect([':', ';']) && this.next(); + body = this.node('block'); while( this.token != this.EOF && this.token !== stopToken && this.token !== this.tok.T_CASE && this.token !== this.tok.T_DEFAULT ) { - result.body.push(this.read_inner_statement()); + items.push(this.read_inner_statement()); } - return result; + return result( + test, items.length > 0 ? body(null, items) : null + ); } }; diff --git a/src/parser/try.js b/src/parser/try.js index bbb9b6ffc..2dc238ffb 100644 --- a/src/parser/try.js +++ b/src/parser/try.js @@ -12,32 +12,33 @@ module.exports = { * )* * (T_FINALLY '{' inner_statement* '}')? * ``` + * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L448 + * @return {Try} */ read_try: function() { - - // @todo implement the short form of declarations this.expect(this.tok.T_TRY); - var result = this.node('try'); - var code = this.nextWithComments().read_statement(); - var allways = false; - var catches = []; - + var result = this.node('try'), + always = null, + body, + catches = [] + ; + body = this.nextWithComments().read_statement(); this.ignoreComments(); + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L455 while(this.token === this.tok.T_CATCH) { - this.next().expect('(').next(); - var exName = this.read_namespace_name(); - var varName = this.read_variable(true, false, false); - this.expect(')').nextWithComments(); - catches.push({ - exception: exName, - as: varName, - body: this.read_statement() - }); + var item = this.node('catch'), what = [], variable = null; + this.next().expect('(') && this.next(); + what = this.read_list( + this.read_namespace_name, '|', false + ); + variable = this.read_variable(true, false, false); + this.expect(')'); + catches.push(item(this.next().read_statement(), what, variable)); this.ignoreComments(); } if (this.token === this.tok.T_FINALLY) { - allways = this.nextWithComments().read_statement(); + always = this.nextWithComments().read_statement(); } - return result(code, catches, allways); + return result(body, catches, always); } }; diff --git a/src/parser/utils.js b/src/parser/utils.js new file mode 100644 index 000000000..bbde78c6c --- /dev/null +++ b/src/parser/utils.js @@ -0,0 +1,84 @@ +/*! + * Defines a list of helper functions for parsing + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ +"use strict"; + +module.exports = { + /** + * Reads a short form of tokens + * @param {Number} token - The ending token + * @return {Block} + */ + read_short_form: function(token) { + var body = this.node('block'), items = []; + if (this.expect(':')) this.next(); + while(this.token != this.EOF && this.token !== token) { + items.push(this.read_inner_statement()); + } + if (this.expect(token)) this.next(); + this.expectEndOfStatement(); + return body(null, items); + } + + /** + * Helper : reads a list of tokens / sample : T_STRING ',' T_STRING ... + * ```ebnf + * list ::= separator? ( item separator )* item + * ``` + */ + ,read_list: function(item, separator, preserveFirstSeparator) { + var result = []; + + if (this.token == separator) { + if (preserveFirstSeparator) result.push(''); + this.next(); + } + + if (typeof (item) === "function") { + do { + result.push(item.apply(this, [])); + if (this.token != separator) { + break; + } + } while(this.next().token != this.EOF); + } else { + if (this.expect(item)) { + result.push(this.text()); + } else { + return []; + } + while (this.next().token != this.EOF) { + if (this.token != separator) break; + // trim current separator & check item + if (this.next().token != item) break; + result.push(this.text()); + } + } + return result; + } + + /** + * Reads a list of names separated by a comma + * + * ```ebnf + * name_list ::= namespace (',' namespace)* + * ``` + * + * Sample code : + * ```php + * var_$prop - what = ['bin', '.', what, ['var', this.text()]]; - } else if (tok === '{') { + what = ['bin', '.', what, ['var', name]]; + } else if (this.token === '{') { // fix $obj->var_{$prop} what = ['bin', '.', what, this.next().read_expr()]; - this.expect('}').next(); + this.expect('}') && this.next(); } break; case this.tok.T_VARIABLE: - what = ['var', this.text()]; + what = this.node('variable'); + var name = this.text().substring(1); this.next(); + what = what(name, false); break; case '$': - this.next().expect(['{', this.tok.T_VARIABLE]); if (this.token === '{') { // $obj->${$varname} what = this.next().read_expr(); - this.expect('}').next(); + this.expect('}') && this.next(); } else { // $obj->$$varname what = this.read_expr(); @@ -143,15 +166,18 @@ module.exports = { break; case '{': what = this.next().read_expr(); - this.expect('}').next(); + this.expect('}') && this.next(); break; default: - what = this.error([this.tok.T_STRING, this.tok.T_VARIABLE]); + this.error([this.tok.T_STRING, this.tok.T_VARIABLE]); // graceful mode : set what as error mode & continue + what = this.node('constref'); + var name = this.text(); this.next(); + what = what(name); break; } - result = ['prop', result, what]; + result = node(result, what); break; default: break recursive_scan_loop; @@ -168,21 +194,29 @@ module.exports = { var text = this.text(); var isDblQuote = text[0] === '"'; text = text.substring(1, text.length - 1); + this.next(); offset = offset( 'string', isDblQuote, this.resolve_special_chars(text) ); } else if (this.token === this.tok.T_NUM_STRING) { - offset = offset('number', this.text()); + var num = this.text(); + this.next(); + offset = offset('number', num); } else if (this.token === this.tok.T_VARIABLE) { - offset = offset('variable', this.text()); + var name = this.text().substring(1); + this.next(); + offset = offset('variable', name, false); } else { this.expect([ this.tok.T_STRING, this.tok.T_NUM_STRING, this.tok.T_VARIABLE ]); + // fallback : consider as text + var text = this.text(); + this.next(); + offset = offset('string', false, text); } - this.next(); return offset; } /** @@ -199,17 +233,19 @@ module.exports = { ,read_reference_variable: function(encapsed, byref) { var result = this.read_simple_variable(byref); while(this.token != this.EOF) { + var node = this.node(); if (this.token == '[') { if (encapsed) { result = this.next().read_encaps_var_offset(); } else { var offset = this.next().token === ']' ? null : this.read_dim_offset(); - result = ['offset', result, offset]; + result = node('offsetlookup', result, offset); } - this.expect(']').next(); + this.expect(']') && this.next(); } else if (this.token == '{' && !encapsed) { - result = ['offset', result, this.next().read_expr()]; - this.expect('}').next(); + var offset = this.next().read_expr(); + this.expect('}') && this.next(); + result = node('offsetlookup', result, offset); } else break; } return result; @@ -221,30 +257,36 @@ module.exports = { */ ,read_simple_variable: function(byref) { var result = this.node('variable'); - if (this.expect([this.tok.T_VARIABLE, '$']).token === this.tok.T_VARIABLE) { + if (this.expect([this.tok.T_VARIABLE, '$']) && this.token === this.tok.T_VARIABLE) { // plain variable name - result = result(this.text(), byref); + var name = this.text().substring(1); this.next(); + result = result(name, byref); } else { + if (this.token === '$') this.next(); // dynamic variable name - switch(this.next().token) { + switch(this.token) { case '{': - result = this.next().read_expr(); - this.expect('}').next(); + var expr = this.next().read_expr(); + this.expect('}') && this.next(); + result = result(expr, byref); break; case '$': // $$$var - result = ['lookup', 'var', this.read_simple_variable(false)]; + result = result(this.read_simple_variable(false), byref); break; case this.tok.T_VARIABLE: // $$var - result = ['var', this.text()]; + var name = this.text().substring(1); + var node = this.node('variable'); this.next(); + result = result(node(name, false), byref); break; default: - result = this.error(['{', '$', this.tok.T_VARIABLE]); + this.error(['{', '$', this.tok.T_VARIABLE]); // graceful mode + var name = this.text(); this.next(); + result = result(name, byref); } - result = ['lookup', 'var', result]; } return result; } diff --git a/test/arrayTests.js b/test/arrayTests.js new file mode 100644 index 000000000..b383006a3 --- /dev/null +++ b/test/arrayTests.js @@ -0,0 +1,184 @@ +var should = require("should"); +var parser = require('../src/index'); + +describe('Array without keys', function() { + + describe('of strings', function () { + // Get result from parser + var ast = parser.parseEval('array("item1", "item2", "item3")'); + + it('should be of type array', function () { + ast.children[0].kind.should.be.exactly("array"); + }); + + it('should have correct number of items', function () { + ast.children[0].items.length.should.be.exactly(3); + }); + + it('should have correct item types and values', function () { + ast.children[0].items[0].value.kind.should.be.exactly("string"); + ast.children[0].items[0].value.value.should.be.exactly("item1"); + + ast.children[0].items[1].value.kind.should.be.exactly("string"); + ast.children[0].items[1].value.value.should.be.exactly("item2"); + + ast.children[0].items[2].value.kind.should.be.exactly("string"); + ast.children[0].items[2].value.value.should.be.exactly("item3"); + }); + }); + + describe('of numbers', function () { + // Get result from parser + var ast = parser.parseEval('array(1, 2.5, 0x1000)'); + + it('should be of type array', function () { + ast.children[0].kind.should.be.exactly("array"); + }); + + it('should have correct number of items', function () { + ast.children[0].items.length.should.be.exactly(3); + }); + + it('should have correct item types and values', function () { + ast.children[0].items[0].value.kind.should.be.exactly("number"); + ast.children[0].items[0].value.value.should.be.exactly('1'); + + ast.children[0].items[1].value.kind.should.be.exactly("number"); + ast.children[0].items[1].value.value.should.be.exactly('2.5'); + + ast.children[0].items[2].value.kind.should.be.exactly("number"); + ast.children[0].items[2].value.value.should.be.exactly('0x1000'); + }); + }); + + describe('of strings and numbers', function () { + // Get result from parser + var ast = parser.parseEval('array(1, "item2", 3, "item4")'); + + it('should be of type array', function () { + ast.children[0].kind.should.be.exactly("array"); + }); + + it('should have correct number of items', function () { + ast.children[0].items.length.should.be.exactly(4); + }); + + it('should have correct item types and values', function () { + ast.children[0].items[0].value.kind.should.be.exactly("number"); + ast.children[0].items[0].value.value.should.be.exactly('1'); + + ast.children[0].items[1].value.kind.should.be.exactly("string"); + ast.children[0].items[1].value.value.should.be.exactly("item2"); + + ast.children[0].items[2].value.kind.should.be.exactly("number"); + ast.children[0].items[2].value.value.should.be.exactly('3'); + + ast.children[0].items[3].value.kind.should.be.exactly("string"); + ast.children[0].items[3].value.value.should.be.exactly("item4"); + }); + }); + + describe('of variables', function () { + // Get result from parser + var ast = parser.parseEval('array($obj1, $obj2, $obj3)'); + + it('should be of type array', function () { + ast.children[0].kind.should.be.exactly("array"); + }); + + it('should have correct number of items', function () { + ast.children[0].items.length.should.be.exactly(3); + }); + + it('should have correct item types and values', function () { + ast.children[0].items[0].value.kind.should.be.exactly("variable"); + ast.children[0].items[0].value.name.should.be.exactly("obj1"); + + ast.children[0].items[1].value.kind.should.be.exactly("variable"); + ast.children[0].items[1].value.name.should.be.exactly("obj2"); + + ast.children[0].items[2].value.kind.should.be.exactly("variable"); + ast.children[0].items[2].value.name.should.be.exactly("obj3"); + }); + }); + + // TODO -- Check this is valid PHP + check AST output is correct + describe('of objects', function () { + // Get result from parser + var ast = parser.parseEval('[new foo(), new stdClass(), new bar()]'); + + it('should be of type array', function () { + ast.children[0].kind.should.be.exactly("array"); + }); + + it('should have correct number of items', function () { + ast.children[0].items.length.should.be.exactly(3); + }); + + it('should have correct item types and values', function () { + ast.children[0].items[0].value.kind.should.be.exactly("new"); + ast.children[0].items[0].value.what.name.should.be.exactly("foo"); + + ast.children[0].items[1].value.kind.should.be.exactly("new"); + ast.children[0].items[1].value.what.name.should.be.exactly("stdClass"); + + ast.children[0].items[2].value.kind.should.be.exactly("new"); + ast.children[0].items[2].value.what.name.should.be.exactly("bar"); + }); + }); + + describe('of arrays', function () { + // Get result from parser + var ast = parser.parseEval([ + 'array(', + ' array("item1", "item2"),', + ' array("item3", "item4"),', + ' array("item5", "item6")', + ')' + ].join('\n')); + + it('should be of type array', function () { + ast.children[0].kind.should.be.exactly("array"); + }); + + it('should have correct number of items', function () { + ast.children[0].items.length.should.be.exactly(3); + }); + + it('should have correct item types and values', function () { + ast.children[0].items[0].value.kind.should.be.exactly("array"); + ast.children[0].items[0].value.items.length.should.be.exactly(2); + ast.children[0].items[0].value.items[0].value.value.should.be.exactly("item1"); + ast.children[0].items[0].value.items[1].value.value.should.be.exactly("item2"); + + ast.children[0].items[1].value.kind.should.be.exactly("array"); + ast.children[0].items[1].value.items.length.should.be.exactly(2); + ast.children[0].items[1].value.items[0].value.value.should.be.exactly("item3"); + ast.children[0].items[1].value.items[1].value.value.should.be.exactly("item4"); + + ast.children[0].items[2].value.kind.should.be.exactly("array"); + ast.children[0].items[2].value.items.length.should.be.exactly(2); + ast.children[0].items[2].value.items[0].value.value.should.be.exactly("item5"); + ast.children[0].items[2].value.items[1].value.value.should.be.exactly("item6"); + }); + }); + + describe('mixed tests / coverage', function() { + it('test short form / keys', function() { + var ast = parser.parseEval('[0 => &$foo, $bar => "foobar"];'); + ast.children[0].items.length.should.be.exactly(2); + ast.children[0].shortForm.should.be.exactly(true); + ast.children[0].items[0].key.kind.should.be.exactly('number'); + ast.children[0].items[0].value.kind.should.be.exactly('variable'); + ast.children[0].items[0].value.byref.should.be.exactly(true); + ast.children[0].items[0].value.name.should.be.exactly('foo'); + ast.children[0].items[0].value.byref.should.be.exactly(true); + ast.children[0].items[1].key.kind.should.be.exactly('variable'); + ast.children[0].items[1].key.name.should.be.exactly('bar'); + ast.children[0].items[1].key.byref.should.be.exactly(false); + }); + + }); + + +}); diff --git a/test/functional/astTests.js b/test/astTests.js similarity index 65% rename from test/functional/astTests.js rename to test/astTests.js index 008b7b7e2..aec942779 100644 --- a/test/functional/astTests.js +++ b/test/astTests.js @@ -1,5 +1,5 @@ var should = require("should"); -var parser = require('../../src/index'); +var parser = require('./main'); describe('Test AST structure', function() { @@ -9,28 +9,6 @@ describe('Test AST structure', function() { ast.children.length.should.be.exactly(0); }); - it('test arrays', function() { - var ast; - - ast = parser.parseEval('\n\narray(\n\t"item1",\n\t"item2",\n\t"item3");\n\n'); - ast.children[0].kind.should.be.exactly('array'); - ast.children[0].shortForm.should.be.exactly(false); - ast.children[0].items.length.should.be.exactly(3); - ast.children[0].items[0].kind.should.be.exactly('entry'); - - ast = parser.parseEval('[0 => &$foo, $bar => "foobar"];'); - ast.children[0].items.length.should.be.exactly(2); - ast.children[0].shortForm.should.be.exactly(true); - ast.children[0].items[0].key.kind.should.be.exactly('number'); - ast.children[0].items[0].value.kind.should.be.exactly('variable'); - ast.children[0].items[0].value.byref.should.be.exactly(true); - ast.children[0].items[0].value.identifier.should.be.exactly('$foo'); - ast.children[0].items[0].value.byref.should.be.exactly(true); - ast.children[0].items[1].key.kind.should.be.exactly('variable'); - ast.children[0].items[1].key.identifier.should.be.exactly('$bar'); - ast.children[0].items[1].key.byref.should.be.exactly(false); - }); - it('test inline', function() { var ast = parser.parseCode('Hello !'); ast.children[0].kind.should.be.exactly('inline'); @@ -70,18 +48,13 @@ describe('Test AST structure', function() { ast.children[3].kind.should.be.exactly('unset'); ast.children[4].kind.should.be.exactly('empty'); }); + it('should be variable', function() { // @todo }); - it('should be assign', function() { - // @todo - }); it('test literals', function() { // @todo string / numbers / booleans }); - it('test namespace', function() { - // @todo - }); it('test constants', function() { var ast = parser.parseEval('const FOO = 3.14;'); @@ -140,36 +113,5 @@ describe('Test AST structure', function() { }); - it('test class', function() { - var ast = parser.parseEval([ - 'final class foo extends bar implements', - ' bim, bam, boum {', - ' const FOO = "azerty";', - ' public static $var;', - ' public function __construct(array $data = null) {', - ' $this->data = $data;', - ' }', - '}', - 'abstract class bar {', - ' /**', - ' * Some informations', - ' */', - ' abstract protected function foo();', - '}' - ].join('\n')); - ast.children.length.should.be.exactly(2); - - ast.children[0].kind.should.be.exactly('class'); - ast.children[1].kind.should.be.exactly('class'); - - ast.children[0].name.should.be.exactly('foo'); - ast.children[1].name.should.be.exactly('bar'); - - ast.children[0].extends.name.should.be.exactly('bar'); - should.equal(ast.children[1].extends, null); - - // @todo test members - console.log(ast.children[0].body); - }); }); diff --git a/test/classTests.js b/test/classTests.js new file mode 100644 index 000000000..cdb46cfdd --- /dev/null +++ b/test/classTests.js @@ -0,0 +1,186 @@ +var should = require("should"); +var parser = require('../src/index'); + +describe('Test classes', function() { + + describe('Validate usual declarations', function() { + var ast = parser.parseEval([ + 'final class foo extends bar implements', + ' bim, bam, boum {', + ' const FOO = "azerty";', + ' public static $var;', + ' public function __construct(array $data = null) {', + ' $this->data = $data;', + ' }', + '}', + 'abstract class bar {', + ' use A, B {', + ' B::smallTalk insteadof A;', + ' A::bigTalk insteadof B, C;', + ' B::bigTalk as public talk;', + ' B::bigTalk as protected talk;', + ' B::bigTalk as private talk;', + ' }', + ' /**', + ' * Some informations', + ' */', + ' abstract protected function &foo() : bar;', + '}' + ].join('\n'), { + parser: { debug: false } + }); + + it('test program size', function() { + ast.children.length.should.be.exactly(2); + }); + + it('test kind', function() { + ast.children[0].kind.should.be.exactly('class'); + ast.children[1].kind.should.be.exactly('class'); + }); + + it('test names', function() { + ast.children[0].name.should.be.exactly('foo'); + ast.children[1].name.should.be.exactly('bar'); + }); + + it('test flags', function() { + ast.children[0].isFinal.should.be.exactly(true); + ast.children[0].isAbstract.should.be.exactly(false); + ast.children[0].isAnonymous.should.be.exactly(false); + ast.children[1].isFinal.should.be.exactly(false); + ast.children[1].isAbstract.should.be.exactly(true); + ast.children[1].isAnonymous.should.be.exactly(false); + }); + + it('test extends', function() { + ast.children[0].extends.name.should.be.exactly('bar'); + should.equal(ast.children[1].extends, null); + }); + + it('test implements', function() { + ast.children[0].implements.length.should.be.exactly(3); + ast.children[0].implements[0].name.should.be.exactly('bim'); + ast.children[0].implements[1].name.should.be.exactly('bam'); + ast.children[0].implements[2].name.should.be.exactly('boum'); + should.equal(ast.children[1].implements, null); + }); + + it('test trait usage', function() { + var use = ast.children[1].body[0]; + /** + ' use A, B {', + ' B::smallTalk insteadof A;', + ' A::bigTalk insteadof B, C;', + ' B::bigTalk as protected talk;', + ' }', + */ + use.kind.should.be.exactly('traituse'); + // test traits names + use.traits.length.should.be.exactly(2); + use.traits[0].name.should.be.exactly('A'); + use.traits[1].name.should.be.exactly('B'); + // test adaptations + use.adaptations.length.should.be.exactly(5); + use.adaptations[0].kind.should.be.exactly('traitprecedence'); + use.adaptations[1].kind.should.be.exactly('traitprecedence'); + use.adaptations[2].kind.should.be.exactly('traitalias'); + + // test adaptation contents + use.adaptations[0].trait.name.should.be.exactly('B'); + use.adaptations[0].method.should.be.exactly('smallTalk'); + use.adaptations[0].instead[0].name.should.be.exactly('A'); + + // test adaptation contents + use.adaptations[1].trait.name.should.be.exactly('A'); + use.adaptations[1].method.should.be.exactly('bigTalk'); + use.adaptations[1].instead[0].name.should.be.exactly('B'); + use.adaptations[1].instead[1].name.should.be.exactly('C'); + + // test adaptation contents + use.adaptations[2].trait.name.should.be.exactly('B'); + use.adaptations[2].method.should.be.exactly('bigTalk'); + use.adaptations[2].as.should.be.exactly('talk'); + use.adaptations[2].visibility.should.be.exactly('public'); + use.adaptations[3].visibility.should.be.exactly('protected'); + use.adaptations[4].visibility.should.be.exactly('private'); + + }); + + it('test methods', function() { + var method = ast.children[1].body[1]; + method.kind.should.be.exactly('method'); + method.isStatic.should.be.exactly(false); + method.isFinal.should.be.exactly(false); + method.isAbstract.should.be.exactly(true); + method.visibility.should.be.exactly('protected'); + method.name.should.be.exactly('foo'); + method.byref.should.be.exactly(true); + // no arguments + method.arguments.length.should.be.exactly(0); + // no body + should.equal(method.body, null); + // check return type + method.type.name.should.be.exactly('bar'); + }); + }); + + describe('Advanced tests', function() { + var ast = parser.parseEval([ + 'class foo implements boo {', + ' use A;', + ' use B { foo as bar; }', + ' // comment', + ' /* boo */', + ' /** doc', + ' * data', + ' foo', + ' */', + ' var $var = true;', + ' final function __construct() { }', + ' private function boo() { }', + '}', + 'interface boo extends something {', + ' // some doc', + ' const A = 1.5;', + ' /** foo */', + ' protected function foo();', + '}', + 'trait line extends foo implements boo {', + ' // some doc', + ' const A = 1.5;', + ' abstract protected function foo();', + '}' + ].join('\n'), { + parser: { extractDoc: true } + }); + + it('check comments', function() { + // @todo + }); + + it('check interface', function() { + // @todo + }); + + it('check traits', function() { + // @todo + }); + + }); + + describe('Test of silent mode', function() { + var ast = parser.parseEval([ + 'class foo {', + ' use A', + ' use B { foo };', + '}' + ].join('\n'), { + parser: { suppressErrors: true } + }); + + it('check use statement errors', function() { + // @todo + }); + }); +}); diff --git a/test/commentTests.js b/test/commentTests.js new file mode 100644 index 000000000..e27ea355d --- /dev/null +++ b/test/commentTests.js @@ -0,0 +1,121 @@ +var should = require("should"); +var parser = require('../src/index'); + +describe('Test comments', function() { + describe('single line comments', function () { + var ast = parser.parseEval([ + '# some information', + '// another line', + '$foo = 123 // 123', + '; /* done */' + ].join('\n'), { + parser: { + extractDoc: true + } + }); + it('test cummulative array', function () { + ast.children.length.should.be.exactly(3); + ast.children[0].kind.should.be.exactly("doc"); + ast.children[0].isDoc.should.be.exactly(false); + ast.children[0].lines.length.should.be.exactly(2); + ast.children[0].lines[0].should.be.exactly('some information'); + ast.children[0].lines[1].should.be.exactly('another line'); + }); + it('test statements', function () { + ast.children[2].kind.should.be.exactly("doc"); + ast.children[2].isDoc.should.be.exactly(false); + ast.children[2].lines[0].should.be.exactly('done'); + }); + it('ignore comments in expression', function () { + ast.children[1].kind.should.be.exactly("assign"); + ast.children[1].left.kind.should.be.exactly('variable'); + ast.children[1].right.kind.should.be.exactly('number'); + }); + }); + + describe('multi line comments', function () { + + var ast = parser.parseEval([ + '/**', + ' * Description', + ' */', + 'function /* ignore */ name(/* */ $arg) {', + '// inner', + 'return $arg /* ignore */;', + '}' + ].join('\n'), { + parser: { + extractDoc: true + } + }); + it('test statements', function () { + ast.children[0].kind.should.be.exactly("doc"); + ast.children[0].lines.length.should.be.exactly(3); + ast.children[0].lines[0].should.be.exactly(''); + ast.children[0].lines[1].should.be.exactly('Description'); + ast.children[0].lines[2].should.be.exactly(''); + }); + it('test function', function () { + ast.children[1].kind.should.be.exactly("function"); + ast.children[1].name.should.be.exactly("name"); + ast.children[1].arguments.length.should.be.exactly(1); + var body = ast.children[1].body.children; + body[0].kind.should.be.exactly('doc'); + // @todo body[1].kind.should.be.exactly('return'); + }); + + }); + + describe('test classes', function () { + var ast = parser.parseEval([ + '/**', + ' * Description', + ' */', + 'class /* ignore */ name /* hehe */ {', + ' // @var test', + ' protected $test, $toto;', + ' // ignored comment', + ' /** @var Class */', + ' static public $foo = 123;', + ' /** ignored also **/', + ' /**', + ' * @return void', + ' */', + ' public function void() { }', + '}' + ].join('\n'), { + parser: { + extractDoc: true + } + }); + it('assume doc block before class', function () { + ast.children[0].kind.should.be.exactly("doc"); + ast.children[1].kind.should.be.exactly("class"); + }); + it('test class elements', function () { + var body = ast.children[1].body; + + body[0].kind.should.be.exactly("doc"); + body[0].lines[0].should.be.exactly("@var test"); + + body[1].kind.should.be.exactly("property"); + body[1].name.should.be.exactly("$test"); + + body[2].kind.should.be.exactly("property"); + body[2].name.should.be.exactly("$toto"); + + body[3].kind.should.be.exactly("doc"); + body[3].lines[0].should.be.exactly("ignored comment"); + + body[4].kind.should.be.exactly("doc"); + body[4].lines[0].should.be.exactly("@var Class"); + + body[5].kind.should.be.exactly("property"); + body[5].name.should.be.exactly("$foo"); + + body[8].kind.should.be.exactly("method"); + body[8].name.should.be.exactly("void"); + }); + }); + +}); diff --git a/test/exprTests.js b/test/exprTests.js new file mode 100644 index 000000000..56cb2e200 --- /dev/null +++ b/test/exprTests.js @@ -0,0 +1,203 @@ +var should = require("should"); +var parser = require('../src/index'); + +describe('Test expressions', function() { + it('test binary', function() { + var ast = parser.parseEval([ + '1 | 3;', + '1 & 3;', + '1 ^ 3;', + '"a" . "b";', + '1 + 3;', + '1 - 3;', + '1 * 3;', + '1 / 3;', + '1 % 3;', + '1 ** 3;', + '1 << 3;', + '1 >> 3;' + ].join('\n')); + + ast.children[0].kind.should.be.exactly('bin'); + ast.children[0].type.should.be.exactly('|'); + ast.children[0].left.value.should.be.exactly('1'); + ast.children[0].right.value.should.be.exactly('3'); + + ast.children[1].kind.should.be.exactly('bin'); + ast.children[1].type.should.be.exactly('&'); + ast.children[1].left.value.should.be.exactly('1'); + ast.children[1].right.value.should.be.exactly('3'); + + ast.children[2].kind.should.be.exactly('bin'); + ast.children[2].type.should.be.exactly('^'); + ast.children[2].left.value.should.be.exactly('1'); + ast.children[2].right.value.should.be.exactly('3'); + // @todo + }); + + it('test boolean', function() { + var ast = parser.parseEval([ + '$a && $b;', + '$a AND $b;', + '$a || $b;', + '$a OR $b;', + '$a XOR $b;', + '$a === $b;', + '$a !== $b;', + '$a == $b;', + '$a != $b;', + '$a > $b;', + '$a < $b;', + '$a >= $b;', + '$a <= $b;', + '$a <=> $b;', + '$a instanceof $b;' + ].join('\n')); + // @todo + }); + + + it('test assignements', function() { + var ast = parser.parseEval([ + '$a = $b;', + '$a .= $b;', + '$a += $b;', + '$a -= $b;', + '$a *= $b;', + '$a **= $b;', + '$a /= $b;', + '$a &= $b;', + '$a |= $b;', + '$a %= $b;', + '$a ^= $b;', + '$a <<= $b;', + '$a >>= $b;' + ].join('\n')); + // @todo + }); + + it('test if based returns', function() { + var ast = parser.parseEval([ + '$a ?? false;', + '$a ? true : false;', + '$a ?: false;' + ].join('\n')); + // @todo + }); + + it('test silent', function() { + var ast = parser.parseEval([ + '@trigger_error();' + ].join('\n')); + ast.children[0].kind.should.be.exactly('silent'); + ast.children[0].expr.kind.should.be.exactly('call'); + }); + + it('test unary', function() { + var ast = parser.parseEval([ + '+$var;', + '~$var;', + '!$var;', + '-$var;' + ].join('\n')); + ast.children[0].kind.should.be.exactly('unary'); + ast.children[0].type.should.be.exactly('+'); + ast.children[0].what.kind.should.be.exactly('variable'); + ast.children[1].kind.should.be.exactly('unary'); + ast.children[1].type.should.be.exactly('~'); + ast.children[1].what.kind.should.be.exactly('variable'); + ast.children[2].kind.should.be.exactly('unary'); + ast.children[2].type.should.be.exactly('!'); + ast.children[2].what.kind.should.be.exactly('variable'); + ast.children[3].kind.should.be.exactly('unary'); + ast.children[3].type.should.be.exactly('-'); + ast.children[3].what.kind.should.be.exactly('variable'); + }); + + it('test cast', function() { + var ast = parser.parseEval([ + '(int)$var;', + '(double)$var;', + '(string)$var;', + '(array)$var;', + '(object)$var;', + '(boolean)$var;', + '(unset)$var;' + ].join('\n')); + ast.children[0].kind.should.be.exactly('cast'); + ast.children[0].type.should.be.exactly('int'); + ast.children[1].kind.should.be.exactly('cast'); + ast.children[1].type.should.be.exactly('double'); + ast.children[2].kind.should.be.exactly('cast'); + ast.children[2].type.should.be.exactly('string'); + ast.children[3].kind.should.be.exactly('cast'); + ast.children[3].type.should.be.exactly('array'); + ast.children[4].kind.should.be.exactly('cast'); + ast.children[4].type.should.be.exactly('object'); + ast.children[5].kind.should.be.exactly('cast'); + ast.children[5].type.should.be.exactly('boolean'); + ast.children[6].kind.should.be.exactly('unset'); + }); + + it('test exit', function() { + var ast = parser.parseEval([ + 'exit(1);', + 'exit();', + 'exit;' + ].join('\n')); + ast.children[0].kind.should.be.exactly('exit'); + ast.children[1].kind.should.be.exactly('exit'); + ast.children[2].kind.should.be.exactly('exit'); + }); + + it('test list statements', function() { + var ast = parser.parseEval([ + 'list($a => list($c,$d,,$e,), $b) = [1, 2];' + ].join('\n'), { + ast: { + withPositions: true + } + }); + // @todo + }); + + it('test incr/decr', function() { + var ast = parser.parseEval([ + '$i++;', + '$i--;', + '++$i;', + '--$i;' + ].join('\n'), { + ast: { + withPositions: true + } + }); + ast.children[0].kind.should.be.exactly('post'); + ast.children[1].kind.should.be.exactly('post'); + ast.children[2].kind.should.be.exactly('pre'); + ast.children[3].kind.should.be.exactly('pre'); + ast.children[0].type.should.be.exactly('+'); + ast.children[1].type.should.be.exactly('-'); + ast.children[2].type.should.be.exactly('+'); + ast.children[3].type.should.be.exactly('-'); + }); + + it('test new', function() { + var ast = parser.parseEval([ + '$a = new foo();', + '$a = new $foo();', + '$a = new class extends foo implements bar { };', + ].join('\n'), { + ast: { debug: false } + }); + ast.children[0].right.kind.should.be.exactly('new'); + ast.children[0].right.what.kind.should.be.exactly('identifier'); + + ast.children[1].right.kind.should.be.exactly('new'); + ast.children[1].right.what.kind.should.be.exactly('variable'); + + ast.children[2].right.kind.should.be.exactly('new'); + ast.children[2].right.what.kind.should.be.exactly('class'); + }); + +}); diff --git a/test/functionTests.js b/test/functionTests.js new file mode 100644 index 000000000..68ec77fae --- /dev/null +++ b/test/functionTests.js @@ -0,0 +1,52 @@ +var should = require("should"); +var parser = require('../src/index'); + +describe('Function tests', function() { + var ast = parser.parseEval([ + 'function &foo($a = 1, callable $b, ?array &...$params) : ?boolean {}', + '$a = function &($b) use($c) : array {', + ' return true;', + '};' + ].join('\n')); + + it('test description', function () { + // Get result from parser + ast.children[0].kind.should.be.exactly('function'); + ast.children[0].name.should.be.exactly('foo'); + ast.children[0].byref.should.be.exactly(true); + ast.children[0].nullable.should.be.exactly(true); + ast.children[0].type.name.should.be.exactly('boolean'); + }); + + it('test arguments', function () { + /* + // 1st param + var arg1 = args[0]; + arg1[0].should.be.exactly('param'); + arg1[1].should.be.exactly('$a'); + should.equal(arg1[2], null); + arg1[3][0].should.be.exactly('number'); + arg1[3][1].should.be.exactly('1'); + arg1[4].should.be.exactly(false, 'not byref'); + arg1[5].should.be.exactly(false, 'not variadic'); + + // 2nd param + var arg2 = args[1]; + arg2[0].should.be.exactly('param'); + arg2[1].should.be.exactly('$params'); + arg2[2][0].should.be.exactly('array'); + should.equal(arg2[3], null); + arg2[4].should.be.exactly(true, 'byref'); + arg2[5].should.be.exactly(true, 'variadic'); + */ + }); + + it('test closure', function () { + // @todo + ast.children[1].right.kind.should.be.exactly('closure'); + var fn = ast.children[1].right; + fn.byref.should.be.exactly(true); + }); + + +}); diff --git a/test/functional/arrayTests.js b/test/functional/arrayTests.js deleted file mode 100644 index dd1a182d5..000000000 --- a/test/functional/arrayTests.js +++ /dev/null @@ -1,157 +0,0 @@ -var should = require("should"); -var parser = require('../../src/index'); - -/*describe('Array without keys', function() { - - describe('of strings', function () { - // Get result from parser - var ast = parser.parseEval('array("item1", "item2", "item3")'); - - it('should be of type array', function () { - ast[1][0][0].should.be.exactly("array"); - }); - - it('should have correct number of items', function () { - ast[1][0][1].length.should.be.exactly(3); - }); - - it('should have correct item types and values', function () { - ast[1][0][1][0].value[0].should.be.exactly("string"); - ast[1][0][1][0].value[1].should.be.exactly("item1"); - - ast[1][0][1][1].value[0].should.be.exactly("string"); - ast[1][0][1][1].value[1].should.be.exactly("item2"); - - ast[1][0][1][2].value[0].should.be.exactly("string"); - ast[1][0][1][2].value[1].should.be.exactly("item3"); - }); - }); - - describe('of numbers', function () { - // Get result from parser - var ast = parser.parseEval('array(1, 2.5, 0x1000)'); - - it('should be of type array', function () { - ast[1][0][0].should.be.exactly("array"); - }); - - it('should have correct number of items', function () { - ast[1][0][1].length.should.be.exactly(3); - }); - - it('should have correct item types and values', function () { - ast[1][0][1][0].value[0].should.be.exactly("number"); - ast[1][0][1][0].value[1].should.be.exactly('1'); - - ast[1][0][1][1].value[0].should.be.exactly("number"); - ast[1][0][1][1].value[1].should.be.exactly('2.5'); - - ast[1][0][1][2].value[0].should.be.exactly("number"); - ast[1][0][1][2].value[1].should.be.exactly('0x1000'); - }); - }); - - describe('of strings and numbers', function () { - // Get result from parser - var ast = parser.parseEval('array(1, "item2", 3, "item4")'); - - it('should be of type array', function () { - ast[1][0][0].should.be.exactly("array"); - }); - - it('should have correct number of items', function () { - ast[1][0][1].length.should.be.exactly(4); - }); - - it('should have correct item types and values', function () { - ast[1][0][1][0].value[0].should.be.exactly("number"); - ast[1][0][1][0].value[1].should.be.exactly('1'); - - ast[1][0][1][1].value[0].should.be.exactly("string"); - ast[1][0][1][1].value[1].should.be.exactly("item2"); - - ast[1][0][1][2].value[0].should.be.exactly("number"); - ast[1][0][1][2].value[1].should.be.exactly('3'); - - ast[1][0][1][3].value[0].should.be.exactly("string"); - ast[1][0][1][3].value[1].should.be.exactly("item4"); - }); - }); - - describe('of variables', function () { - // Get result from parser - var ast = parser.parseEval('array($obj1, $obj2, $obj3)'); - - it('should be of type array', function () { - ast[1][0][0].should.be.exactly("array"); - }); - - it('should have correct number of items', function () { - ast[1][0][1].length.should.be.exactly(3); - }); - - it('should have correct item types and values', function () { - ast[1][0][1][0].value[0].should.be.exactly("var"); - ast[1][0][1][0].value[1].should.be.exactly("$obj1"); - - ast[1][0][1][1].value[0].should.be.exactly("var"); - ast[1][0][1][1].value[1].should.be.exactly("$obj2"); - - ast[1][0][1][2].value[0].should.be.exactly("var"); - ast[1][0][1][2].value[1].should.be.exactly("$obj3"); - }); - }); - - // TODO -- Check this is valid PHP + check AST output is correct - describe('of objects', function () { - // Get result from parser - var ast = parser.parseEval('[new foo(), new stdClass(), new bar()]'); - - it('should be of type array', function () { - ast[1][0][0].should.be.exactly("array"); - }); - - it('should have correct number of items', function () { - ast[1][0][1].length.should.be.exactly(3); - }); - - it('should have correct item types and values', function () { - ast[1][0][1][0].value[0].should.be.exactly("new"); - ast[1][0][1][0].value[1][0].should.be.exactly("ns"); - ast[1][0][1][0].value[1][1][0].should.be.exactly("foo"); - - ast[1][0][1][1].value[0].should.be.exactly("new"); - ast[1][0][1][1].value[1][0].should.be.exactly("ns"); - ast[1][0][1][1].value[1][1][0].should.be.exactly("stdClass"); - - ast[1][0][1][2].value[0].should.be.exactly("new"); - ast[1][0][1][2].value[1][0].should.be.exactly("ns"); - ast[1][0][1][2].value[1][1][0].should.be.exactly("bar"); - }); - }); - - describe('of arrays', function () { - // Get result from parser - var ast = parser.parseEval('array(array("item1", "item2"), array("item3", "item4"), array("item5", "item6"))'); - - it('should be of type array', function () { - ast[1][0][0].should.be.exactly("array"); - }); - - it('should have correct number of items', function () { - ast[1][0][1].length.should.be.exactly(3); - }); - - it('should have correct item types and values', function () { - ast[1][0][1][0].value[0].should.be.exactly("array"); - ast[1][0][1][0].value[1].should.be.match([{ key: false, value: ["string", "item1"] }, { key: false, value: ["string", "item2"] }]); - - ast[1][0][1][1].value[0].should.be.exactly("array"); - ast[1][0][1][1].value[1].should.be.match([{ key: false, value: ["string", "item3"] }, { key: false, value: ["string", "item4"] }]); - - ast[1][0][1][2].value[0].should.be.exactly("array"); - ast[1][0][1][2].value[1].should.be.match([{ key: false, value: ["string", "item5"] }, { key: false, value: ["string", "item6"] }]); - }); - }); - -});*/ diff --git a/test/functional/commentTests.js b/test/functional/commentTests.js deleted file mode 100644 index c9fb615b7..000000000 --- a/test/functional/commentTests.js +++ /dev/null @@ -1,121 +0,0 @@ -var should = require("should"); -var parser = require('../../src/index'); - -/*describe('Test comments', function() { - describe('single line comments', function () { - var ast = parser.parseEval([ - '# some information', - '// another line', - '$foo = 123 // 123', - '; // done' - ].join('\n'), { - parser: { - extractDoc: true - } - }); - it('test cummulative array', function () { - ast[1][0][0].should.be.exactly("comment"); - ast[1][0][1].length.should.be.exactly(2); - ast[1][0][1][0].should.be.exactly('# some information\n'); - ast[1][0][1][1].should.be.exactly('// another line\n'); - }); - it('test statements', function () { - ast[1][2][0].should.be.exactly("comment"); - ast[1][2][1].length.should.be.exactly(1); - ast[1][2][1][0].should.be.exactly('// done'); - }); - it('ignore comments in expression', function () { - ast[1][1][0].should.be.exactly("set"); - ast[1][1][1][0].should.be.exactly('var'); - ast[1][1][2][0].should.be.exactly('number'); - }); - }); - - describe('multi line comments', function () { - - var ast = parser.parseEval([ - '/**', - ' * Description', - ' *-/', - 'function /* ignore *-/ name(/* *-/ $arg) {', - '// inner', - 'return $arg /* ignore *-/;', - '}' - ].join('\n'), { - parser: { - extractDoc: true - } - }); - it('test statements', function () { - ast[1][0][0].should.be.exactly("doc"); - ast[1][0][1].should.be.exactly([ - '/**', - ' * Description', - ' *-/' - ].join('\n')); - - }); - it('test function', function () { - ast[1][1][0].should.be.exactly("function"); - ast[1][1][1].should.be.exactly("name"); - ast[1][1][2].length.should.be.exactly(1); - var body = ast[1][1][5]; - body[0][0].should.be.exactly('comment'); - body[1][0].should.be.exactly('return'); - }); - - }); - - describe('test classes', function () { - var ast = parser.parseEval([ - '/**', - ' * Description', - ' *-/', - 'class /* ignore *-/ name /* hehe *-/ {', - ' // @var test', - ' protected $test, $toto;', - ' // ignored comment', - ' /** @var Class *-/', - ' static public $foo = 123;', - ' /** ignored also **-/', - ' /**', - ' * @return void', - ' *-/', - ' public function void() { }', - '}' - ].join('\n'), { - parser: { - extractDoc: true - } - }); - it('assume doc block before class', function () { - ast[1][0][0].should.be.exactly("doc"); - ast[1][1][0].should.be.exactly("class"); - }); - it('test class elements', function () { - var body = ast[1][1][5]; - - body[0][0].should.be.exactly("comment"); - body[0][1][0].should.be.exactly("// @var test\n"); - - body[1][0].should.be.exactly("var"); - body[1][1].should.be.exactly("$test"); - - body[2][0].should.be.exactly("var"); - body[2][1].should.be.exactly("$toto"); - - body[3][0].should.be.exactly("comment"); - body[3][1][0].should.be.exactly("// ignored comment\n"); - - body[4][0].should.be.exactly("doc"); - body[4][1].should.be.exactly("/** @var Class *-/"); - - body[5][0].should.be.exactly("var"); - body[5][1].should.be.exactly("$foo"); - - body[8][0].should.be.exactly("method"); - body[8][1].should.be.exactly("void"); - }); - }); - -});*/ diff --git a/test/functional/functionTests.js b/test/functional/functionTests.js deleted file mode 100644 index 1a947ab36..000000000 --- a/test/functional/functionTests.js +++ /dev/null @@ -1,36 +0,0 @@ -var should = require("should"); -var parser = require('../../src/index'); - -/*describe('Function tests', function() { - - it('test variadic', function () { - // Get result from parser - var ast = parser.parseEval('function &foo($a = 1, array &...$params) {}'); - var fn = ast[1][0]; - fn[0].should.be.exactly('function'); - fn[1].should.be.exactly('foo'); - - var args = fn[2]; - args.length.should.be.exactly(2); - - // 1st param - var arg1 = args[0]; - arg1[0].should.be.exactly('param'); - arg1[1].should.be.exactly('$a'); - should.equal(arg1[2], null); - arg1[3][0].should.be.exactly('number'); - arg1[3][1].should.be.exactly('1'); - arg1[4].should.be.exactly(false, 'not byref'); - arg1[5].should.be.exactly(false, 'not variadic'); - - // 2nd param - var arg2 = args[1]; - arg2[0].should.be.exactly('param'); - arg2[1].should.be.exactly('$params'); - arg2[2][0].should.be.exactly('array'); - should.equal(arg2[3], null); - arg2[4].should.be.exactly(true, 'byref'); - arg2[5].should.be.exactly(true, 'variadic'); - }); - -});*/ diff --git a/test/functional/locationTests.js b/test/functional/locationTests.js deleted file mode 100644 index d789bc317..000000000 --- a/test/functional/locationTests.js +++ /dev/null @@ -1,27 +0,0 @@ -var should = require("should"); -var parser = require('../../src/index'); - -/*describe('Test offsets', function() { - - describe('to check offsets', function() { - - // init a new parser instance - var text = [ - ' // a comment ', - 'echo "string";' - ].join('\r\n'); - var ast = parser.parseEval( - text, - { - parser: { - locations: true - } - } - ); - /** @fixme should test & fix offsets **-/ - // console.log(ast[1]); - - }); - -}); -*/ diff --git a/test/functional/gracefulTests.js b/test/gracefulTests.js similarity index 67% rename from test/functional/gracefulTests.js rename to test/gracefulTests.js index 8ca4520f1..b183c077b 100644 --- a/test/functional/gracefulTests.js +++ b/test/gracefulTests.js @@ -1,7 +1,7 @@ var should = require("should"); -var parser = require('../../src/index'); +var parser = require('../src/index'); -/*describe('Test graceful mode', function() { +describe('Test graceful mode', function() { describe('to suppress errors', function() { @@ -21,16 +21,17 @@ var parser = require('../../src/index'); '}', // 4. '}' // 5. <-- extra '}' token here ].join('\n')); - ast[2].length.should.be.exactly(2); - ast[1][0][2][5][0][2][0].should.be.exactly('error'); + ast.errors.length.should.be.exactly(2); + // @todo ast[1][0][2][5][0][2][0].should.be.exactly('error'); }); it('test expr', function () { var ast = test.parseEval('$a = $b -; $foo = $a;'); - ast[2].length.should.be.exactly(2); - ast[1].length.should.be.exactly(2); + ast.errors.length.should.be.exactly(2); + ast.children.length.should.be.exactly(2); + /** @todo ast[1][0][2][0].should.be.exactly('bin'); ast[1][0][2][1].should.be.exactly('-'); ast[1][0][2][3][0].should.be.exactly('error'); @@ -38,14 +39,16 @@ var parser = require('../../src/index'); ast[1][1][0].should.be.exactly('set'); ast[1][1][1][0].should.be.exactly('var'); ast[1][1][1][1].should.be.exactly('$foo'); + */ }); it('test class', function () { var ast = test.parseEval('class foo { foo const A = 1 '); - ast[2].length.should.be.exactly(3); - ast[1].length.should.be.exactly(1); + ast.errors.length.should.be.exactly(3); + ast.children.length.should.be.exactly(1); + /** @todo ast[1][0][0].should.be.exactly('class'); ast[1][0][1].should.be.exactly('foo'); ast[1][0][5].length.should.be.exactly(2); // including the foo error @@ -53,18 +56,20 @@ var parser = require('../../src/index'); ast[1][0][5][1][0].should.be.exactly('const'); ast[1][0][5][1][1].should.be.exactly('A'); ast[1][0][5][1][2][1].should.be.exactly('1'); + */ }); it('test flags', function () { - var ast = test.parseEval('final final interface foo { abstract function func() '); - ast[2].length.should.be.exactly(4); - ast[1].length.should.be.exactly(2); - ast[1][0][0].should.be.exactly('error'); - ast[1][1][0].should.be.exactly('interface'); + var ast = test.parseEval([ + 'final final interface foo {', + ' abstract function func() ' + ].join('\n')); + ast.errors.length.should.be.exactly(4); + ast.children.length.should.be.exactly(1); + ast.children[0].kind.should.be.exactly('interface'); }); }); }); -*/ diff --git a/test/ifTests.js b/test/ifTests.js new file mode 100644 index 000000000..ccda96f78 --- /dev/null +++ b/test/ifTests.js @@ -0,0 +1,105 @@ +var should = require("should"); +var parser = require('../src/index'); + +describe('Test IF statements', function() { + describe('Test common cases', function() { + var ast = parser.parseEval([ + 'if (true) {', + ' echo "is true";', + '} else if (false) {', + ' echo "false";', + '} elseif (false) {', + ' echo "2nd";', + '} else {', + ' echo "else";', + '}' + ].join('\n'), { + parser: { debug: false } + }); + it('test if structure', function() { + ast.children.length.should.be.exactly(1); + ast.children[0].kind.should.be.exactly('if'); + ast.children[0].shortForm.should.be.exactly(false); + ast.children[0].test.kind.should.be.exactly('boolean'); + ast.children[0].test.value.should.be.exactly(true); + ast.children[0].body.children.length.should.be.exactly(1); + ast.children[0].body.children[0].kind.should.be.exactly('echo'); + }); + it('test else branches', function() { + var el1 = ast.children[0].alternate; + el1.kind.should.be.exactly('if'); + el1.test.kind.should.be.exactly('boolean'); + el1.test.value.should.be.exactly(false); + el1.body.children[0].kind.should.be.exactly('echo'); + el1.body.children[0].arguments[0].value.should.be.exactly('false'); + + var el2 = el1.alternate; + el2.kind.should.be.exactly('if'); + el2.body.children[0].kind.should.be.exactly('echo'); + el2.body.children[0].arguments[0].value.should.be.exactly('2nd'); + + var el3 = el2.alternate; + el3.kind.should.be.exactly('block'); + el3.children[0].kind.should.be.exactly('echo'); + el3.children[0].arguments[0].value.should.be.exactly('else'); + }); + }); + describe('Test short form', function() { + var ast = parser.parseEval([ + 'if (true):', + ' echo "is true";', + 'elseif (false):', + ' echo "false";', + 'else:', + ' echo "else";', + 'endif;' + ].join('\n'), { + parser: { debug: false } + }); + it('should be shortForm flagged', function() { + ast.children.length.should.be.exactly(1); + ast.children[0].kind.should.be.exactly('if'); + ast.children[0].shortForm.should.be.exactly(true); + }); + it('test else branches', function() { + var el1 = ast.children[0].alternate; + el1.shortForm.should.be.exactly(true); + var el2 = el1.alternate; + el2.kind.should.be.exactly('block'); + }); + }); + describe('Improve coverage', function() { + var ast = parser.parseEval([ + 'if (true):', + ' echo "is true";', + 'elseif (false):', + ' echo "false";', + 'elseif (false):', + ' echo "false";', + 'endif;', + 'if (true):', + ' echo "is true";', + 'else:', + ' echo "false";', + 'endif;' + ].join('\n'), { + parser: { debug: false } + }); + it('should have 2 childs', function() { + ast.children.length.should.be.exactly(2); + ast.children[0].kind.should.be.exactly('if'); + ast.children[0].shortForm.should.be.exactly(true); + ast.children[1].kind.should.be.exactly('if'); + ast.children[1].shortForm.should.be.exactly(true); + }); + it('test else branches', function() { + var el1 = ast.children[0].alternate; + el1.kind.should.be.exactly('if'); + var el2 = el1.alternate; + el2.kind.should.be.exactly('if'); + should.equal(el2.alternate, null); // no else + // else block + ast.children[1].alternate.kind.should.be.exactly('block'); + }); + }); +}); diff --git a/test/lexerTests.js b/test/lexerTests.js new file mode 100644 index 000000000..40bfe22e5 --- /dev/null +++ b/test/lexerTests.js @@ -0,0 +1,65 @@ +var should = require("should"); +var parser = require('./main'); + +describe('Test lexer', function() { + describe('initial state', function() { + var ast = parser.parseCode([ + '', + '', + '<% echo $b; %>', + '<%= $b %>' + ].join('\n'), { + lexer: { + short_tags: true, + asp_tags: true + } + }); + it('parse short tag', function() { + ast.children[0].kind.should.be.exactly('echo'); + ast.children[0].arguments[0].kind.should.be.exactly('variable'); + ast.children[0].arguments[0].name.should.be.exactly('a'); + }); + it('parse short echo', function() { + ast.children[1].kind.should.be.exactly('echo'); + ast.children[1].arguments[0].kind.should.be.exactly('variable'); + ast.children[1].arguments[0].name.should.be.exactly('a'); + }); + it('parse asp tag', function() { + ast.children[2].kind.should.be.exactly('echo'); + ast.children[2].arguments[0].kind.should.be.exactly('variable'); + ast.children[2].arguments[0].name.should.be.exactly('b'); + }); + it('parse asp echo tag', function() { + ast.children[3].kind.should.be.exactly('echo'); + ast.children[3].arguments[0].kind.should.be.exactly('variable'); + ast.children[3].arguments[0].name.should.be.exactly('b'); + }); + }); + + describe('test comments', function() { + it('should work ^^', function() { + var ast = parser.parseCode([ + '', + '<%', + ' // another line %>', + '', + ' $v\n";', + 'foreach([[1,2], [3,4]] as list($a, $b) => [$c, $d]):', + 'echo "$a -> $b\n";', + 'endforeach;' + ].join('\n'), { + parser: { debug: false } + }); + it('test kind & form', function() { + ast.children[0].kind.should.be.exactly('foreach'); + ast.children[0].shortForm.should.be.exactly(false); + ast.children[1].kind.should.be.exactly('foreach'); + ast.children[1].shortForm.should.be.exactly(true); + + }); + it('test source', function() { + ast.children[0].source.kind.should.be.exactly('variable'); + ast.children[0].source.byref.should.be.exactly(true); + ast.children[0].source.name.should.be.exactly('foo'); + ast.children[1].source.kind.should.be.exactly('array'); + ast.children[1].source.items.length.should.be.exactly(2); + }); + it('test key', function() { + should.equal(ast.children[0].key, null); + ast.children[1].key.kind.should.be.exactly('list'); + ast.children[1].key.arguments.length.should.be.exactly(2); + }); + it('test value', function() { + ast.children[0].value.kind.should.be.exactly('variable'); + ast.children[0].value.name.should.be.exactly('v'); + ast.children[1].value.kind.should.be.exactly('array'); + ast.children[1].value.shortForm.should.be.exactly(true); + }); + it('test body', function() { + ast.children[0].body.kind.should.be.exactly('echo'); + ast.children[1].body.kind.should.be.exactly('block'); + ast.children[1].body.children[0].kind.should.be.exactly('echo'); + }); + }); + +}); diff --git a/test/main.js b/test/main.js new file mode 100644 index 000000000..9d7b5790c --- /dev/null +++ b/test/main.js @@ -0,0 +1,11 @@ +/*! + * Defines a list of helpers for tests + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ + +var parser = require('../src/index'); +// @todo : move here the debug code +// @todo : add an automated token check (with php7) +module.exports = parser; diff --git a/test/namespaceTest.js b/test/namespaceTest.js new file mode 100644 index 000000000..85f973356 --- /dev/null +++ b/test/namespaceTest.js @@ -0,0 +1,85 @@ +var should = require("should"); +var parser = require('../src/index'); + +describe('Test namespace statements', function() { + + var singleNs = parser.parseEval([ + 'namespace foo;', + ' use bar\\baz as barBaz;', + ' use const bar\\baz as barBaz, baz\\boo as bazBoo;', + ' use function bar\\baz as barBaz, baz\\boo as bazBoo;', + ' use bar\\baz {', + ' const FOO as BAZ_FOO,', + ' function BOO as BAZ_BOO', + ' };', + ' use const azerty {', + ' A as AZERTY_A,', + ' B as AZERTY_B', + ' };', + // relative namespace + ' $a = namespace\\barBaz;', + // fully qualified + ' $b = \\barBaz;', + // qualified + ' $c = barBaz\\foo;', + // unqualified + ' $d = barBaz;' + ].join('\n'), { + parser: { debug: false } + }); + + var multiNs = parser.parseEval([ + 'namespace \\foo {', + ' $i++;', + '}', + 'namespace {', + ' $b++;', + '}' + ].join('\n'), { + parser: { debug: false } + }); + + var nsKeyword = parser.parseEval([ + 'namespace\\foo();', + '$var = namespace\\bar;', + ].join('\n'), { + parser: { debug: false } + }); + + var nsError = parser.parseEval([ + 'namespace $var = true;', + ].join('\n'), { + parser: { debug: false, suppressErrors: true } + }); + + it('check namespace', function() { + // @todo + }); + + it('check use', function() { + // @todo + }); + + it('check resolution', function() { + // @todo + }); + + it('check silent mode', function() { + nsError.errors.length.should.be.exactly(2); + nsError.errors[0].line.should.be.exactly(1); + nsError.errors[1].line.should.be.exactly(1); + nsError.children[0].kind.should.be.exactly('namespace'); + nsError.children[0].name.name.should.be.exactly(''); + nsError.children[0].children[0].kind.should.be.exactly('assign'); + nsError.children[0].children[0].left.kind.should.be.exactly('variable'); + nsError.children[0].children[0].right.kind.should.be.exactly('boolean'); + }); + + it('check namespace keyword', function() { + nsKeyword.children[0].kind.should.be.exactly('call'); + nsKeyword.children[0].what.kind.should.be.exactly('identifier'); + nsKeyword.children[0].what.resolution.should.be.exactly('rn'); + nsKeyword.children[0].what.name.should.be.exactly('foo'); + // @todo : test second child + }); +}); diff --git a/test/numberTests.js b/test/numberTests.js new file mode 100644 index 000000000..795177901 --- /dev/null +++ b/test/numberTests.js @@ -0,0 +1,41 @@ +var should = require("should"); +var parser = require('./main'); + +describe('Test numbers', function() { + + describe('comon tests', function() { + var ast = parser.parseEval([ + '$a = -1.5;', + '$b = 1234;', + '$c = 9223372036854775807;', + '$c = 9223372036854775808;', + '$d = 0x1A;', + '$d = 0xFF;', + '$e = 0b1011;', + '$f = 0123;', + '$g = 1.2e3;', + '$h = 7E-10;' + ].join('\n')); + it('should be float', function() { + ast.children[0].right.kind.should.be.exactly('number'); + ast.children[0].right.value.should.be.exactly('-1.5'); + }); + + }); + // @fixme should test bad syntaxes + // like 01239 (octal number with bad token) + describe('edge tests', function() { + var ast = parser.parseEval([ + '$a = 0xx;', + '$b = 0b2;', + '$c = 01239;', + '$d = 7E-a;', + '$e = 7EX;' + ].join('\n'), { + parser: { + suppressErrors: true + } + }); + + }); +}); diff --git a/test/parser/class.parser b/test/parser/class.parser deleted file mode 100644 index 3efbd9ed1..000000000 --- a/test/parser/class.parser +++ /dev/null @@ -1,156 +0,0 @@ -Test class parser ---PASS:https://github.com/HvyIndustries/crane/issues/153-- -class nette_2_4_PhpReflection { - public static function getClassTree(\ReflectionClass $class) - { - $addTraits = function ($types) use (& $addTraits) { - if ($traits = array_merge(...array_map('class_uses', array_values($types)))) { - $types += $traits + $addTraits($traits); - } - return $types; - }; - $class = $class->getName(); - return array_values($addTraits([$class] + class_parents($class) + class_implements($class))); - } -} ---PASS-- -interface a1 extends i1, i2 { - const A1 = 123; - public function a1(); - protected function a1(); -} ---PASS-- -class a { - protected static $οbject = array(); -} ---PASS-- -class a { - const e=5; - const f=6; - const A=(self::e | self::f); -} ---FAIL-- -class a1 { - echo 123; -} ---FAIL-- -interface a1 extends i1, i2 { - private const A1 = 123; -} ---FAIL-- -interface a1 extends i1, i2 { - private function A(); -} ---FAIL-- -interface a1 { - public function A() { - // non-sense - } -} ---PASS-- -class a1 { - public function b1() { - // nothing - } -} -$var = 'a1'; -$a = new $var(); ---PASS @todo handle interfaces -- -// test -class titi { - const FOO = 123; - static protected $var; -} -class toto extends titi implements tata {} ---PASS-- -abstract class aa { } ---PASS-- -final class aa { } ---PASS-- -class titi { } -class /** aa **/ toto - extends titi - implements tata, coincoin { - /** - * Hi - */ -} ---FAIL-- -class { } ---FAIL-- -class zz; ---FAIL-- -abstract final class zz { } ---FAIL-- -class a extends implements { } ---FAIL-- -class extends { } ---FAIL-- -class implements { } ---FAIL-- -class a implements { } ---FAIL-- -class a { - const B; -} ---PASS-- -final class aa { - const AAAA = 1; - const MY_CONST = 'azerty'; - /** - * azerty - */ - const ZZZ = 3, YYY = 4; -} ---PASS-- -abstract class aa { - public $a; - private $b; - protected $d; - - public $a = 'foo'; - /** - * azerty - */ - static public $e, $z = 777; - - public static $f; - var $g; - var $h , $i; -} ---PASS-- -class foo { - public function aa() { - /** code here **/ - } - public static function bb($arg1, $arg2 = 123) { - /** code here **/ - } - /** - * @return void - */ - final static protected function bb() { - /** code here **/ - } - function aa($b) { - } -} ---PASS-- -class foo { - static public $a = 123; - protected static $b, $c; - private static $d = array(); - // aaa -} ---PASS-- -class singleton { - static protected $instance; - final private function __constuct() { } - static public function getInstance() { - if (!self::$instance) { - self::$instance = new static(); - } - return self::$instance; - } -} -$var = singleton::getInstance(); diff --git a/test/parser/code-igniter.parser b/test/parser/code-igniter.parser deleted file mode 100644 index d65a5d533..000000000 --- a/test/parser/code-igniter.parser +++ /dev/null @@ -1,21 +0,0 @@ -Some special functions on CodeIgniter 3.1.0 ---PASS-- -class foo { - public function __construct($config = array()) - { - $this->CI =& get_instance(); - $this->CI->load->language('profiler'); - - // default all sections to display - foreach ($this->_available_sections as $section) - { - if ( ! isset($config[$section])) - { - $this->_compile_{$section} = TRUE; - } - } - - $this->set_sections($config); - log_message('info', 'Profiler Class Initialized'); - } -} diff --git a/test/parser/expr.parser b/test/parser/expr.parser deleted file mode 100644 index 758ae8833..000000000 --- a/test/parser/expr.parser +++ /dev/null @@ -1,76 +0,0 @@ -Test expr parser ---PASS-- -class foo { - function aa() { - $parent_resource = " in '$this->parent->template_resource}'"; - } -} ---PASS-- -$a = 1 + 2; -$a++; -$a--; -++$a; ---$a; ---PASS-- -$b = (3 + 4) * $a / 2; ---PASS-- -$b ^= $a | $b; -$b |= $a ^ $b; -$b **= $a % $b; -$b %= $a ** $b; -$b <<= $a >> $b; -$b >>= $a << $b; ---PASS-- -$b = $a OR $b; -$b = $a AND $b; -$b = $a XOR $b; -$b = $a > $b; -$b = $a instanceof $b; -$b = $a >= $b; -$b = $a <= $b; -$b = $a == $b; -$b = $a != $b; ---PASS-- -@silent_fail(); ---PASS-- -$data = foo()['offset']; -foo()['offset'] = 'something'; ---PASS-- -list($a, $b) = array(1, 2); -$b = empty($a); ---PASS-- -$arg = include($a); -$arg = @include_once($a); -$arg = require($a); -$arg = require_once($a); -$b = @eval($arg); ---PASS-- -$a = (int)$b; -$a = (double)$b; -$a = (unset)$b; -$a = (bool)$b; -$a = (string)$b; -$a = (array)$b; -$a = (object)$b; -print 'done'; -exit(0); -exit; ---PASS-- -$var = new class extends foo { -}; -list(list($a, $b), $c) = [ - [1, 2], 3 -]; ---PASS-- -echo "test: {$this->test->foo}"; -$var = &new foo(); ---PASS-- -$var += $a; -$var -= $a; -$var *= $a; -$var /= $a; -$var .= $a; -$var &= $a; -$var |= $a; ---PASS-- -$exec = `pstree -ap $process {$foo->bar}`; diff --git a/test/parser/fibo.parser b/test/parser/fibo.parser deleted file mode 100644 index 12ce2ac68..000000000 --- a/test/parser/fibo.parser +++ /dev/null @@ -1,10 +0,0 @@ -Test algorithms ---PASS-- -function fibo($x) { - if ($x < 2) { - return $x; - } else { - return fibo($x - 1) + fibo($x - 2); - } -} -echo fibo(20); \ No newline at end of file diff --git a/test/parser/function.parser b/test/parser/function.parser deleted file mode 100644 index a327445d5..000000000 --- a/test/parser/function.parser +++ /dev/null @@ -1,70 +0,0 @@ -Test function parser ---PASS-- -function aa($a, $b = MY_CONST, $c = A | B) { } ---PASS-- -function htmlspecialchars( - string $string, - int $flags = ENT_COMPAT | ENT_HTML401, - string $encoding = 'ini_get("default_charset")', - bool $double_encode = true -): string {} ---FAIL-- -function aa(); ---PASS ??-- -function aa() {}; ---FAIL-- -function aa($b;) {} ---FAIL-- -function $aa($b) {} ---FAIL-- -function 123__aa() { } ---PASS-- -function _123aa() { } ---PASS-- -function _3aa() { } ---PASS-- -function aa() { } ---PASS-- -function a123a() { } ---PASS-- -function __aa() { } ---PASS-- -function aa(){ -} ---PASS-- -/** - * This is a comment - */ -function aa( /** here another comment **/ ){ - // here is another comment -} - ---PASS-- -function &aa() { } ---PASS-- -function aa($a) { } ---PASS-- -function aa(array $a) { } ---PASS-- -function aa(array &$a) { } ---PASS-- -function aa(array &$a = [1, 2, 3]) { } ---PASS-- -function aa(array &$a, $b) { } ---PASS-- -function aa(&$a) { } ---PASS-- -function aa( - &$a, $b -) { - -} - ---PASS-- -function aa(&$a, $b = 5) { - echo 'Hello world'; -} -function aa(&$a, $b = null) { } -function aa(&$a, $b = true) { } -function aa(&$a, $b = "aa") { } -function aa(&$a, $b = array('a' => 'b')) { } \ No newline at end of file diff --git a/test/parser/if.parser b/test/parser/if.parser deleted file mode 100644 index f4231eee2..000000000 --- a/test/parser/if.parser +++ /dev/null @@ -1,19 +0,0 @@ -Test IF / ELSE / ELSEIF statements ---PASS-- -if ($offset !== false) { - unset($this->_packages[$offset]); -} elseif ($elseCond) { - echo 'Something else'; -} else { - echo 'else'; -} ---PASS:Short form-- -if ($offset !== false): - doSomething(); - echo 'ok'; -elseif ($var === 'foo'): - doSomethingElse(); - echo 'elseif'; -else: - echo 'else'; -endif; \ No newline at end of file diff --git a/test/parser/loops.parser b/test/parser/loops.parser deleted file mode 100644 index c190bfcbe..000000000 --- a/test/parser/loops.parser +++ /dev/null @@ -1,39 +0,0 @@ -Test FOR / FOREACH / WHILE ---PASS:for-- -for($i = 0; $i < 10; $i++) { - echo $i; -} ---PASS:empty for-- -for(;;) { - echo ++$i; - if ($i > 10) break; -} ---PASS:for short-- -for($i = 0; $i < 10; $i++): - echo $i; -endfor; ---PASS:while-- -while(++$i < 10) { - echo $i; -} ---PASS:while short form-- -while(++$i < 10): - echo $i; -endwhile; ---PASS:do-- -do { - echo $i; -} while(++$i < 10); ---PASS:foreach-- -foreach($argv as $offset => &$arg) { - echo $offset . ' -> ' . $arg; -} ---PASS:foreach short form-- -foreach($argv as $offset => &$arg): - echo $offset . ' -> ' . $arg; -endforeach; - ---PASS:foreach list-- -foreach($argv as list($a, $b)) { - echo $a . ' -> ' . $b; -} \ No newline at end of file diff --git a/test/parser/namespace.parser b/test/parser/namespace.parser deleted file mode 100644 index b8324e017..000000000 --- a/test/parser/namespace.parser +++ /dev/null @@ -1,32 +0,0 @@ -Test namespaces ---PASS-- -namespace MyNameSpace\SubNameSpace; -echo true; ---PASS-- -echo 'before'; -namespace { - echo 'inside'; -}; -echo 'after'; ---PASS-- -namespace MyNameSpace\SubNameSpace { - echo 123; -} ---PASS:@todo-- -namespace \MyNameSpace\SubNameSpace { - -} ---PASS-- -use My\Full\NSname; ---PASS-- -use My\Full\Classname as Another; ---PASS-- -use function My\Full\functionName; ---PASS-- -use function My\Full\functionName as func; ---PASS-- -use const My\Full\CONSTANT; -use const framework\ClassName\CONSTANT as constantAlias; ---PASS-- -use My\Full\Classname, My\Full\NSname; -use My\Full\Classname as Another, My\Full\NSname; diff --git a/test/parser/php7.parser b/test/parser/php7.parser deleted file mode 100644 index 41f853912..000000000 --- a/test/parser/php7.parser +++ /dev/null @@ -1,132 +0,0 @@ -Test PHP7 syntax ---PASS:Return type declarations-- -function arraysSum(array ...$arrays): array -{ - return array_map(function(array $array): int { - return array_sum($array); - }, $arrays); -} - -print_r(arraysSum([1,2,3], [4,5,6], [7,8,9])); ---PASS-- -// Fetches the value of $_GET['user'] and returns 'nobody' -// if it does not exist. -$username = $_GET['user'] ?? 'nobody'; -// This is equivalent to: -$username = isset($_GET['user']) ? $_GET['user'] : 'nobody'; ---PASS:Spaceship operator-- -// Integers -echo 1 <=> 1; // 0 -echo 1 <=> 2; // -1 -echo 2 <=> 1; // 1 - -// Floats -echo 1.5 <=> 1.5; // 0 -echo 1.5 <=> 2.5; // -1 -echo 2.5 <=> 1.5; // 1 - -// Strings -echo "a" <=> "a"; // 0 -echo "a" <=> "b"; // -1 -echo "b" <=> "a"; // 1 ---PASS:Constant arrays using define()-- -define('ANIMALS', [ - 'dog', - 'cat', - 'bird' -]); ---PASS:Anonymous classes-- -interface Logger { - public function log(string $msg); -} - -class Application { - private $logger; - - public function getLogger(): Logger { - return $this->logger; - } - - public function setLogger(Logger $logger) { - $this->logger = $logger; - } -} - -$app = new Application; -$app->setLogger(new class implements Logger { - public function log(string $msg) { - echo $msg; - } -}); - -var_dump($app->getLogger()); ---PASS:Unicode codepoint escape syntax-- - -echo "\u{aa}"; -echo "\u{0000aa}"; -echo "\u{9999}"; ---PASS:Closure::call()-- - -class A {private $x = 1;} - -// Pre PHP 7 code -$getXCB = function() {return $this->x;}; -$getX = $getXCB->bindTo(new A, 'A'); // intermediate closure -echo $getX(); - -// PHP 7+ code -$getX = function() {return $this->x;}; -echo $getX->call(new A); ---PASS:Group use declarations-- -// Pre PHP 7 code -use some\ns\ClassA; -use some\ns\ClassB; -use some\ns\ClassC as C; - -use function some\ns\fn_a; -use function some\ns\fn_b; -use function some\ns\fn_c; - -use const some\ns\ConstA; -use const some\ns\ConstB; -use const some\ns\ConstC; - -// PHP 7+ code -use some\ns\{ClassA, ClassB, ClassC as C}; -use function some\ns\{fn_a, fn_b, fn_c}; -use const some\ns\{ConstA, ConstB, ConstC}; ---PASS:Generator Return Expressions-- -$gen = (function() { - yield 1; - yield 2; - - return 3; -})(); - -foreach ($gen as $val) { - echo $val, PHP_EOL; -} - -echo $gen->getReturn(), PHP_EOL; ---PASS:Generator delegation-- -function gen() -{ - yield 1; - yield 2; - yield from gen2(); -} - -function gen2() -{ - yield 3; - yield 4; -} - -foreach (gen() as $val) -{ - echo $val, PHP_EOL; -} ---PASS-- -(clone $foo)->bar(); -class foo { static $bar = 'baz'; } -var_dump('foo'::$bar); diff --git a/test/parser/scalar.parser b/test/parser/scalar.parser deleted file mode 100644 index eca8053ac..000000000 --- a/test/parser/scalar.parser +++ /dev/null @@ -1,22 +0,0 @@ -Test scalar values ---PASS-- -$var = array( - 1 => true, - 2 => false, - 3 => 'azerty', - 'a' => [ - 4, - 5, - 6 => array( - __FILE__, - __DIR__, - __LINE__, - __NAMESPACE__, - ) - ], -); ---PASS-- -$var[] = 123; ---PASS-- -$num = 1.23; -$num = -1.23; \ No newline at end of file diff --git a/test/parser/statement.parser b/test/parser/statement.parser deleted file mode 100644 index 6dc41cf60..000000000 --- a/test/parser/statement.parser +++ /dev/null @@ -1,55 +0,0 @@ -Test statements ---PASS-- -if ( true ) { } ---PASS-- -if ( true ); ---PASS-- -if ( true ) echo 'Hello'; ---PASS-- -for($a = 1; $b < 10; $c++) echo $d; ---PASS-- -foreach([1, 2, 3] as $i => $k); ---PASS-- -do { - $i++; -} while(true); ---PASS-- -while(true) { - $i++; -} ---PASS-- -switch(true) { - case 1: break; - case 2: break; - default: break; -} ---PASS-- -try { - $i++; -} catch(CustomException $e) { - $i--; -} catch(Exception $e) { - $i--; -} finally { - unset($i); -} ---PASS-- -namespace a { - const A = 1, B = 2; - if (true) { - interface foo { - } - class bar { - } - trait boo { - } - function baz() { - } - } -} ---PASS-- -declare(ticks=1) { - haha: - throw new Exception('foo'); - goto haha; -} diff --git a/test/parser/strings.parser b/test/parser/strings.parser deleted file mode 100644 index 8474b44ac..000000000 --- a/test/parser/strings.parser +++ /dev/null @@ -1,28 +0,0 @@ -Test parsing strings ---PASS-- -$foo = "123"; ---PASS-- -$bar = "result is : $foo"; ---PASS-- -echo 'ceci est une\nchaîne simple'; ---PASS-- -echo 'Arnold a dit : "I\'ll be back"'; ---PASS-- -echo 'Vous pouvez également ajouter des nouvelles lignes -dans vos chaînes -de cette façon'; ---PASS-- -$here = <<foo. -Maintenant, j'affiche quelques {$foo->bar[1]}. -Et ceci devrait afficher un 'A' majuscule : \x41 -EOT; \ No newline at end of file diff --git a/test/parser/switch.parser b/test/parser/switch.parser deleted file mode 100644 index b79d41877..000000000 --- a/test/parser/switch.parser +++ /dev/null @@ -1,15 +0,0 @@ -Test switch statements ---PASS-- -switch($var) { - case 1: - $a = 1; - break; - case 2: - case 3: - $a = 2; - break; - case null: - $a = 'should be 3 - coz no break'; - default: - $a = 3; -} \ No newline at end of file diff --git a/test/parser/trait.parser b/test/parser/trait.parser deleted file mode 100644 index c475dc5d6..000000000 --- a/test/parser/trait.parser +++ /dev/null @@ -1,49 +0,0 @@ -Test the traits parsing ---PASS-- -trait ezcReflectionReturnInfo { - function getReturnType() { /*1*/ } - function getReturnDescription() { /*2*/ } -} - -class ezcReflectionMethod extends ReflectionMethod { - use ezcReflectionReturnInfo; - /* ... */ -} - -class ezcReflectionFunction extends ReflectionFunction { - use ezcReflectionReturnInfo; - /* ... */ -} ---PASS-- -trait A { - public function smallTalk() { - echo 'a'; - } - public function bigTalk() { - echo 'A'; - } -} - -trait B { - public function smallTalk() { - echo 'b'; - } - public function bigTalk() { - echo 'B'; - } -} - -class Talker { - use A, B { - B::smallTalk insteadof A; - A::bigTalk insteadof B; - } -} - -class Aliased_Talker { - use A, B { - B::smallTalk insteadof A; - A::bigTalk insteadof B; - B::bigTalk as talk; - } -} \ No newline at end of file diff --git a/test/parser/try.parser b/test/parser/try.parser deleted file mode 100644 index 1cda36994..000000000 --- a/test/parser/try.parser +++ /dev/null @@ -1,9 +0,0 @@ -Test try / catch / finally statements ---PASS-- -try { - $result = 1 / 0; -} catch(Exception $e) { - echo $e->__toString(); -} finally { - echo 'Result = ' . $result; -} \ No newline at end of file diff --git a/test/parser/vars.parser b/test/parser/vars.parser deleted file mode 100644 index ddca8329a..000000000 --- a/test/parser/vars.parser +++ /dev/null @@ -1,39 +0,0 @@ -Test statements ---PASS-- - $varname = 1; ---PASS-- - $$varvar = 1; ---PASS-- - ${$varname} = 1; - if (isset(${$varname})) { - echo 'Hello World'; - } ---PASS-- - $$$varname = 1; ---FAIL-- - $'VARNAME' = 1; ---FAIL-- - $test$var = 1; ---FAIL-- - foreach($var as echo) { - } ---PASS-- - $test{$var--} = 1; ---PASS-- - foo(); ---PASS-- - $var = \ns\foo; ---PASS-- - $foo->bar->baz(true, 123)->$varvar; ---PASS-- - foo::bar; ---PASS-- - foo::$bar; ---PASS-- - $foo::$bar; ---PASS-- - $foo::$bar[123]->baz['azerty']; ---FAIL-- - $foo::$bar[123]->baz['azerty']->'azerty'; ---FAIL-- - foo::echo; \ No newline at end of file diff --git a/test/php-langspec b/test/php-langspec deleted file mode 160000 index 469835002..000000000 --- a/test/php-langspec +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4698350023adf64d072843341d37ae93bb2bdb20 diff --git a/test/position.js b/test/position.js deleted file mode 100644 index 94db74d34..000000000 --- a/test/position.js +++ /dev/null @@ -1,64 +0,0 @@ -var reader = require('../src/index'); -reader.parser.locations = true; -var code = require('fs').readFileSync(__dirname + '/proto/foo.php').toString(); -console.log(code); -var AST = reader.parseCode(code); - -console.log('------------------ AST :'); -var func = AST[1][0]; -// the result -console.log( '\nAST : ', func); -// the function code : -console.log( '\nPHP : >' + code.substring( func[1][2], func[2][2]) + '<' ); -// the function AST -console.log( '\nFUNCTION : ', func[3]); - -var cls = AST[1][1]; -// the result -console.log( '\nAST : ', cls); -// the class code : -console.log( '\nPHP : >' + code.substring( cls[1][2], cls[2][2]) + '<' ); -// the class AST -console.log( '\nCLASS : ', cls[3][5]); - - -var method = cls[3][5].methods[0]; -// the result -console.log( '\nAST : ', method); -// the class code : -console.log( '\nPHP : >' + code.substring( method[1][2], method[2][2]) + '<' ); -// the class AST -console.log( '\nMETHOD : ', method[3]); - -var prop = cls[3][5].properties[0]; -// the result -console.log( '\nAST : ', prop); -// the class code : -console.log( '\nPHP : >' + code.substring( prop[1][2], prop[2][2]) + '<' ); -// the class AST -console.log( '\nPROPERTY : ', prop[3]); - -var variable = prop[3][0]; -// the result -console.log( '\nAST : ', variable); -// the class code : -console.log( '\nPHP : >' + code.substring( variable[1][2], variable[2][2]) + '<' ); -// the class AST -console.log( '\nVARIABLE : ', variable[3]); - - -var itf = AST[1][2]; -// the result -console.log( '\nAST : ', itf); -// the class code : -console.log( '\nPHP : >' + code.substring( itf[1][2], itf[2][2]) + '<' ); -// the class AST -console.log( '\nINTERFACE : ', itf[3]); - -var cst = itf[3][4].constants[0]; -// the result -console.log( '\nAST : ', cst); -// the class code : -console.log( '\nPHP : >' + code.substring( cst[1][2], cst[2][2]) + '<' ); -// the class AST -console.log( '\nCONSTANT : ', cst[3]); diff --git a/test/proto/class/class.js b/test/proto/class/class.js deleted file mode 100644 index 51b758c00..000000000 --- a/test/proto/class/class.js +++ /dev/null @@ -1,186 +0,0 @@ - -// using http://ejohn.org/blog/simple-javascript-inheritance/ -var Class = require('../glayzzle/src/compat/class'); - -// declare the bar class -var bar = (function() { - // private static vars - var this_var1 = 'bar'; - // a private static function (costs memory alloc for every object) - function privateFunction() { - console.log('You call a private function from bar !'); - } - // define the parent handler - var parent = Class.prototype; - - // class declaration - var self = Class.__extends({ - name: 'bar' - , final: false - , abstract: false - // declare static propected properties - , protected: { - var1: 'protected-var-bar', - yop: function() { - console.log(self.yop); - } - } - }, { - // declare a public var - arg: null, - var2: 'public-bar', - // public constructor - __construct: function(arg1) { - // constructor code - this.arg = arg1; - this_var1 += ' : ' + arg1; - }, - // public function - bar: function() { - console.log('I am the public BAR function : '+this_var1+' !'); - }, - // try to check this scope - doSomething: function() { - console.log('Do something on current scope : '); - privateFunction(); - this.bar(); - } - }); - return self.__class; -}()); - -// static public vars -bar.static_var2 = 'bar2'; -// static public method -bar.getInstance = function() { - // bar == self - return bar.static_var2; -}; - -console.log('*** TEST BEHAVIOUR WITH BAR ***'); - -var i1 = new bar('azerty'); -i1.bar(); - -var i1_1 = new bar('azerty123'); -i1_1.bar(); - -console.log(i1); -console.log(i1 instanceof bar); -console.log(bar); -console.log(bar.getInstance()); - -/** TEST EXTENDS **/ -console.log('*** TEST EXTENSION WITH FOO ***'); -var foo = (function() { - // private static vars with no collision - var this_var1 = 'foo'; - // a private static function (costs memory alloc for every object) - function privateFunction() { - console.log('You call a private function from foo !'); - } - // define the parent handler - var parent = bar.prototype; - - // class declaration - var self = bar.__extends({ - name: 'foo' - , final: true - , abstract: false - , protected: { - } - }, { - // declare a public var - var2: 'public-foo', - // public function - bar: function() { - privateFunction(); - console.log('I am the public FOO function : '+this_var1+' !'); - parent.bar(); - }, - getYop: function() { - return self.var1; - } - }); - return self.__class; -}()); - -var i2 = new foo('test-foo'); -i2.bar(); -console.log(i2); -console.log(i2 instanceof bar); -i2.doSomething(); - -/** TEST STATIC OVERRIDES **/ -console.log('*** TEST STATIC EXTENSION WITH FOO ***'); -foo.static_var2 = 'var2-from-foo'; -console.log(foo); -console.log(foo.getInstance()); -// static public method -foo.getInstance = function() { - // this == static - return this.static_var2; -}; -console.log(foo.getInstance()); - - -/** TEST FINAL **/ -console.log('*** TEST FINAL OPTION WITH OUPS ***'); -try { - var oups = (function() { - // define the parent handler - var parent = foo.prototype; - // class declaration - return foo.__extends({ - name: 'oups' - }, { - // empty class body ... - }); - }()); -} catch(e) { - console.log('Expected error : ' + e.message); -} - -/** TEST PROTECTED VALUES **/ -console.log('*** TEST PROTECTED ***'); -console.log(i1.yop); // expect to be undefined -console.log(i2.getYop()); - -/** BENCHMARKS **/ -console.log('*** RUNNING SOME PERF TESTS ***'); -var POJO = function() { - // empty proto -}; -var POPO = (function() { - return Class.__extends({ name: 'POPO' }, { - // empty body - }).__class; -}()); - -console.log('=> constructor test over 1M calls'); -function runPOJO_Tests(out) { - if (out) console.log('--- start POJO bench : '); - var start = Date.now(); - var items = []; - - for(var i = 0; i < 1000000; i++) { - items.push(new POJO()); - } - - if (out) console.log('POJO Duration : ' + (Date.now() - start) + ' msec'); -} - -function runPOPO_Tests(out) { - if (out) console.log('--- start POPO bench : '); - var start = Date.now(); - var items = []; - - for(var i = 0; i < 1000000; i++) { - items.push(new POPO()); - } - - if (out) console.log('POPO Duration : ' + (Date.now() - start) + ' msec'); -} - -runPOPO_Tests(true); -runPOJO_Tests(true); \ No newline at end of file diff --git a/test/proto/class/classProtected.js b/test/proto/class/classProtected.js deleted file mode 100644 index 06af5d862..000000000 --- a/test/proto/class/classProtected.js +++ /dev/null @@ -1,42 +0,0 @@ - -// using http://ejohn.org/blog/simple-javascript-inheritance/ -var Class = require('../glayzzle/src/compat/class'); - -// declare the bar class -var bar = (function() { - // class declaration - return Class.__extends({ - // public constructor - __construct: function(def) { - - var protectedVar = (def && def.protectedVar) || "protectedVar"; - - // privileged function - this.getProtectedVar = function() { - return protectedVar; - }; - } - }); -}()); - -// declare the bar class -var barChild = (function() { - // class declaration - return bar.__extends({ - // public constructor - __construct: function(def) { - this._super({ - protectedVar: "inheritedProtectedVar" - }); - } - }).__class; -}()); - -var myBar = new bar(); -var myBarChild = new barChild(); - -console.log("TEST PROTECTED"); -console.log("Protected on super", (myBar.protectedVar == undefined) , myBar.protectedVar); -console.log("Protected through super getter", (myBar.getProtectedVar() == "protectedVar"), myBar.getProtectedVar()); -console.log("Protected on inherited", (myBarChild.protectedVar == undefined) , myBarChild.protectedVar); -console.log("Protected through inherited getter", (myBarChild.getProtectedVar() == "inheritedProtectedVar"), myBarChild.getProtectedVar()); \ No newline at end of file diff --git a/test/proto/class/simple.js b/test/proto/class/simple.js deleted file mode 100644 index 9df3c9459..000000000 --- a/test/proto/class/simple.js +++ /dev/null @@ -1,38 +0,0 @@ -var Class = require('../../glayzzle/src/compat/class'); - -"use strict"; - -// declare the foo class -var foo = Class('foo') - .public({ - name: 'John Doe', - __construct: function() { - console.log('Hello world'); - } - }) - .static({ - public: { - foo: 123 - } - }) -.getPrototype(); - -// create an instance -var john = new foo(); -console.log('--', john.name); - -// declare the foo class -var bar = Class('bar') - .extends(foo) - .public({ - name: 'John Bar', - __construct: function() { - console.log('Hello bar'); - } - }) -.getPrototype(); - -// create an instance -var john = new bar(); -console.log('--', john.name); - diff --git a/test/proto/class/test.php b/test/proto/class/test.php deleted file mode 100644 index 632217296..000000000 --- a/test/proto/class/test.php +++ /dev/null @@ -1,17 +0,0 @@ -bar = $bar; - } - public function foo() { return ++$this->foo; } - public static function bar() { - return new self(123); - } -} - -$foo = new foo('azerty'); -echo $foo->foo() . "\n"; -echo $foo->bar . "\n"; -echo foo::bar()->bar . "\n"; \ No newline at end of file diff --git a/test/proto/foo.php b/test/proto/foo.php deleted file mode 100644 index 20e1dc571..000000000 --- a/test/proto/foo.php +++ /dev/null @@ -1,32 +0,0 @@ -a = $a; - } - } - - interface FOOBAR { - const BAR = 123; - function shouldDo(bar $a); - } - -/** - -__c: { - bar: function(a) { - // private functions & properties - // public functions & properties - return { - a: null - }; - } -} - -*/ \ No newline at end of file diff --git a/test/proto/main.js b/test/proto/main.js deleted file mode 100644 index 0fd090562..000000000 --- a/test/proto/main.js +++ /dev/null @@ -1,6 +0,0 @@ -var PHP = require('../src/php'); -PHP.include('./foo.php'); -console.log('Foo Result : ' + PHP.foo("Hello World")); - -var bar = new PHP.bar('azerty'); -console.log('Bar result : ' + bar.foo); diff --git a/test/proto/test1.php b/test/proto/test1.php deleted file mode 100644 index 4021b1197..000000000 --- a/test/proto/test1.php +++ /dev/null @@ -1,12 +0,0 @@ -$colors<\\n";'); + }); + it('...', function() { + var ast = parser.parseEval('echo B"\\colors[1] contains >$colors[1]<\\n";'); + }); + it('...', function() { + var ast = parser.parseEval('echo "\\colors[1] contains >$colors [1]<\\n";'); + }); + it('...', function() { + var ast = parser.parseEval('var_dump("$colors[1]");'); + }); + it('...', function() { + var ast = parser.parseEval('var_dump("$colors[01]");'); + }); + it('...', function() { + var ast = parser.parseEval('var_dump("$colors[0x1]");'); + }); + it('...', function() { + var ast = parser.parseEval('var_dump("$colors[0X1]");'); + }); + it('...', function() { + var ast = parser.parseEval('echo "~\'.{{$expectedLength}}\'\\$~s";'); + }); + it('...', function() { + var ast = parser.parseEval('echo "Hello \\"$obj->name\\" !";'); + }); + it('...', function() { + var ast = parser.parseEval('echo "Hello {".$obj->name."} !";'); + }); + it('...', function() { + var ast = parser.parseEval('echo "Hello {$obj->name} !";'); + }); + it('...', function() { + var ast = parser.parseEval('echo "Hello ${obj}->name !";'); + }); + it('...', function() { + var ast = parser.parseEval('echo "\\"$parts[0]\\"\\n";'); + }); + it('...', function() { + var ast = parser.parseEval('echo "${$parts[$i]}\\n";'); + }); + it('...', function() { + var ast = parser.parseEval('echo "yo : {$feeds[0][\'title[0][value]\']}";'); + }); + it('...', function() { + var ast = parser.parseEval('return "\\x1B[{$color}m{$str}\\x1B[0m";'); + }); + it('test double quotes', function() { + var ast = parser.parseEval([ + '$a = "$";', + '$a = "{";', + '$a = "-$-";', + '$a = "-{";', + '$a = "$b";', + '$a = "{$b}";', + '$a = "${$b}";', + '$a = "-$b?";', + '$a = "-{$b}";', + '$a = "-${$b}";', + '$a = "";', + '$a = "\\"";', + ].join('\r\n'), { + lexer: { + debug: false + }, + parser: { + debug: false + } + }); + }); + it('...', function() { + var ast = parser.parseEval('$foo = array("v1.09azAZ-._~!$", true);'); + }); + it('...', function() { + var ast = parser.parseEval('$v = strtolower("$i.$j.$k-$rel");'); + }); + it('...', function() { + var ast = parser.parseEval('$text = "$text at line $line";'); + }); + it('...', function() { + var ast = parser.parseEval('return "Class.create(\'$package$className\',{";'); + }); + it('heredoc ...', function() { + var ast = parser.parseEval([ + '$code = <<<\t EOFX', + '', + '/*{$this->docStar}', + ' * Constructor.', + ' */', + 'public function __construct()', + '${$targetDirs}', + '$test', + 'EOFX;' + ].join('\r\n')); + }); + it('heredoc ...', function() { + var ast = parser.parseEval([ + '$code .= <<<\'EOF\'', + ' }', + 'EOF;' + ].join('\r\n')); + }); + it('heredoc ...', function() { + var ast = parser.parseEval([ + '$fallbackContent .= sprintf(<<addFallbackCatalogue(\\$catalogue%s);', + 'EOF2', + ');', + ].join('\r\n')); + }); + it('test empty nowdoc & heredoc contents', function() { + var ast = parser.parseEval([ + 'echo <<addFallbackCatalogue(\\$catalogue%s);' + ].join('\r'), { + parser: { + suppressErrors: true + } + }); + }); + it('test nowdoc end of doc', function() { + var ast = parser.parseEval([ + '$a = <<<\'EOF2\'', + '\\$catalogue%s = new MessageCatalogue(\'%s\', %s);', + '\\$catalogue%s->addFallbackCatalogue(\\$catalogue%s);' + ].join('\r'), { + parser: { + suppressErrors: true + } + }); + }); + it('test backquotes', function() { + var ast = parser.parseEval([ + '$a = `ls $cwd`;', + '$a = `ls ${$cwd}`;', + '$a = `ls {$cwd}`;', + '$a = `$var`;', + '$a = `${var}`;', + '$a = `{$var}`;', + '$a = ``;', + '$a = `\\``;', + '$a = `{`;', + '$a = `-{`;', + '$a = `-$`;', + '$a = `$`;', + ].join('\r')); + }); + +}); diff --git a/test/switchTests.js b/test/switchTests.js new file mode 100644 index 000000000..c3a5de583 --- /dev/null +++ b/test/switchTests.js @@ -0,0 +1,75 @@ +var should = require("should"); +var parser = require('../src/index'); + +describe('Test SWITCH statements', function() { + var ast = parser.parseEval([ + 'switch(true) {', + ' case 1:', + ' case $var:', + ' $foo = false;', + ' break;', + ' case FOO:', + ' $foo = true;', + ' break;', + ' default:', + ' $bar = false;', + '}', + 'switch(true):; ?> bug arg; \ No newline at end of file diff --git a/test/token/beaba b/test/token/beaba deleted file mode 160000 index 80c70a116..000000000 --- a/test/token/beaba +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 80c70a1168151626741433df1f14eb6fbe68d7b6 diff --git a/test/token/callable.php b/test/token/callable.php deleted file mode 100644 index 6ae02ef1f..000000000 --- a/test/token/callable.php +++ /dev/null @@ -1,45 +0,0 @@ - - - - \ No newline at end of file diff --git a/test/token/evernote-cloud-sdk-php b/test/token/evernote-cloud-sdk-php deleted file mode 160000 index bd46dc6fe..000000000 --- a/test/token/evernote-cloud-sdk-php +++ /dev/null @@ -1 +0,0 @@ -Subproject commit bd46dc6fed41796bcfb22a65cfe1f709aec21d71 diff --git a/test/token/heredoc.php b/test/token/heredoc.php deleted file mode 100644 index 55f27e574..000000000 --- a/test/token/heredoc.php +++ /dev/null @@ -1,75 +0,0 @@ -exportTargetDirs(); - - $code = <<docStar} - * Constructor. - */ - public function __construct() - {{$targetDirs} -EOFX; - - if ($this->container->getParameterBag()->all()) { - $code .= "\n \$this->parameters = \$this->getDefaultParameters();\n"; - } - - $code .= "\n \$this->services = array();\n"; - $code .= $this->addMethodMap(); - $code .= $this->addAliases(); - - $code .= <<<'EOF' - } - -EOF; - - return $code; - } - - -$fallbackContent .= sprintf(<<addFallbackCatalogue(\$catalogue%s); -EOF2 -); - -/* @todo : should pass : */ - $js =<<<"EOJ" -EOJ - . "text"; - - $opml = <<dump}} -EOF1; - - $expected = <<<'EXPECTED' -$no_index_value_scalar = TRUE; -$no_index_value_foo['foo']['value'] = NULL; // comment -EXPECTED -; - - $expected = <<test} -BAR; diff --git a/test/token/laravel b/test/token/laravel deleted file mode 160000 index 1ac0a0bbd..000000000 --- a/test/token/laravel +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1ac0a0bbda864ab29b8972a03a984a3ed5034df5 diff --git a/test/token/magento1 b/test/token/magento1 deleted file mode 160000 index 4e32a61d6..000000000 --- a/test/token/magento1 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4e32a61d61abcdb8615aa46fde3c49681012b4a1 diff --git a/test/token/magento2 b/test/token/magento2 deleted file mode 160000 index 4bc9fcc56..000000000 --- a/test/token/magento2 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4bc9fcc56b57953b8c3b9e752a187c80e091706f diff --git a/test/token/math.php b/test/token/math.php deleted file mode 100644 index 1cbfdbd64..000000000 --- a/test/token/math.php +++ /dev/null @@ -1,73 +0,0 @@ - 10) { - echo '>10'; - } else if ($c < 1) { - echo '<1'; - } else if ($c >= 5) { - echo '>=5'; - } else if ($c <= 2) { - echo '<=2'; - } else if ($c != 2) { - echo '!=2'; - } else if ($c <> 2) { - echo '<>2'; - } else if ($c !== 2) { - echo '!==2'; - } else if ($c == 2) { - echo '==2'; - } else if ($c === 2) { - echo '===2'; - } - $d += $c >> 2; - $d /= ($d << 2) - (4 ** 5); - if ($d >>= 5) { - $d *= $d << 2; - } else if ($d <<= 5) { - $d **= 2; - } - - Require_Once(__file__); - for($i = 0; $i < 100; $i++) { - $obj[$i]->${$var . $i} -= (int)$i ^ 5 + ($j--); - } - MyClass::$property .= 'aa'.'bb'; - $foo %= 2 % 6; - $foo &= 5; - - if ($foo && $bar || $baz) { - $draw |= $tom & $jerry | ( string )$mickey; - } - - $var = $arg ? 0: 5; - - foreach(gen_three_nulls() as $key => $value) { - $key = $bar ? null : $foo ** $baz ^ (int * $a5); - if ($key ^= 5) echo '!!'; - } - - - function gen_three_nulls(...$arg) { - foreach (range(1, 3) as $i) { - yield; - } - - $doc = << 1; // 0 -echo 1 <=> 2; // -1 -echo 2 <=> 1; // 1 - -// Floats -echo 1.5 <=> 1.5; // 0 -echo 1.5 <=> 2.5; // -1 -echo 2.5 <=> 1.5; // 1 - -// Strings -echo "a" <=> "a"; // 0 -echo "a" <=> "b"; // -1 -echo "b" <=> "a"; // 1 - -// Constant arrays using define() - -define('ANIMALS', [ - 'dog', - 'cat', - 'bird' -]); - -echo ANIMALS[1]; // outputs "cat" - -// Anonymous classes - -interface Logger { - public function log(string $msg); -} - -class Application { - private $logger; - - public function getLogger(): Logger { - return $this->logger; - } - - public function setLogger(Logger $logger) { - $this->logger = $logger; - } -} - -$app = new Application; -$app->setLogger(new class implements Logger { - public function log(string $msg) { - echo $msg; - } -}); - -var_dump($app->getLogger()); - -// Unicode codepoint escape syntax - -echo "\u{aa}"; -echo "\u{0000aa}"; -echo "\u{9999}"; - -// Closure::call() - -class A {private $x = 1;} - -// Pre PHP 7 code -$getXCB = function() {return $this->x;}; -$getX = $getXCB->bindTo(new A, 'A'); // intermediate closure -echo $getX(); - -// PHP 7+ code -$getX = function() {return $this->x;}; -echo $getX->call(new A); - -// Group use declarations - -// Pre PHP 7 code -use some\ns\ClassA; -use some\ns\ClassB; -use some\ns\ClassC as C; - -use function some\ns\fn_a; -use function some\ns\fn_b; -use function some\ns\fn_c; - -use const some\ns\ConstA; -use const some\ns\ConstB; -use const some\ns\ConstC; - -// PHP 7+ code -use some\ns\{ClassA, ClassB, ClassC as C}; -use function some\ns\{fn_a, fn_b, fn_c}; -use const some\ns\{ConstA, ConstB, ConstC}; - -// Generator Return Expressions - -$gen = (function() { - yield 1; - yield 2; - - return 3; -})(); - -foreach ($gen as $val) { - echo $val, PHP_EOL; -} - -echo $gen->getReturn(), PHP_EOL; - -// Generator delegation - -function gen() -{ - yield 1; - yield 2; - yield from gen2(); -} - -function gen2() -{ - yield 3; - yield 4; -} - -foreach (gen() as $val) -{ - echo $val, PHP_EOL; -} - -(clone $foo)->bar(); - -// USERS NOTES - -class foo { static $bar = 'baz'; } -var_dump('foo'::$bar); - diff --git a/test/token/simple.php b/test/token/simple.php deleted file mode 100644 index 6d44c3df0..000000000 --- a/test/token/simple.php +++ /dev/null @@ -1,10 +0,0 @@ -Hello world and or \ No newline at end of file diff --git a/test/token/symfony b/test/token/symfony deleted file mode 160000 index 45b557a5a..000000000 --- a/test/token/symfony +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 45b557a5a7461738fc615cb80fc4076cbbdc251d diff --git a/test/token/tag.php b/test/token/tag.php deleted file mode 100644 index 7d224e983..000000000 --- a/test/token/tag.php +++ /dev/null @@ -1,8 +0,0 @@ -<%= "this is asp mode tag"; // %> -<% echo "this is asp mode tag"; // %> - - - - - - diff --git a/test/token/tcpdf b/test/token/tcpdf deleted file mode 160000 index 009f2304c..000000000 --- a/test/token/tcpdf +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 009f2304c3a9c8152b89a5321a8825f250911dc3 diff --git a/test/token/texts.php b/test/token/texts.php deleted file mode 100644 index a623295c9..000000000 --- a/test/token/texts.php +++ /dev/null @@ -1,40 +0,0 @@ -$colors<\n"; - echo B"\colors[1] contains >$colors[1]<\n"; - echo "\colors[1] contains >$colors [1]<\n"; // whitespace permitted, but semantics change - //echo "\colors[1] contains >$colors[ 1]<\n"; // whitespace not permitted - //echo "\colors[1] contains >$colors[1 ]<\n"; // whitespace not permitted - var_dump("$colors[1]"); - var_dump("$colors[01]"); // invalid index - var_dump("$colors[0x1]"); // invalid index - var_dump("$colors[0X1]"); // invalid index - - echo "~'.{{$expectedLength}}'\$~s"; - $obj = new stdClass(); - $obj->name = 'john'; - if ($obj->name[0] == "{") echo 1; - echo "Hello \"$obj->name\" !"; - echo "Hello {".$obj->name."} !"; - echo "Hello {$obj->name} !"; - echo "Hello ${obj}->name !"; - echo "\"$parts[0]\"\n"; - // @fixme (from lexer) echo "${$parts[$i]}\n"; - echo "yo : {$feeds[0]['title[0][value]']}"; - return "\x1B[{$color}m{$str}\x1B[0m"; - $tiny = "$"; - $foo = array("v1.09azAZ-._~!$", true); - $v = strtolower("$i.$j.$k-$rel"); - $text = "$text at line $line"; - return "Class.create('$package$className',{"; - - $this->lastTTYMode = trim(`stty -g`); - - /**, $methodName = null **/ - $source = preg_replace('/(^|\s)namespace(.*?)\s*;/', "$1namespace$2\n{", $source)."}\n"; - /*/ - $foo; - /**/ - $foo; diff --git a/test/token/yii2 b/test/token/yii2 deleted file mode 160000 index 560e3eb0a..000000000 --- a/test/token/yii2 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 560e3eb0a36f71101ca4bf7b55f86615758dc0e5 diff --git a/test/token/zf2 b/test/token/zf2 deleted file mode 160000 index 81ccf073b..000000000 --- a/test/token/zf2 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 81ccf073bf0602d073ad0bd4b27dd6d4593e8839 diff --git a/test/variableTests.js b/test/variableTests.js new file mode 100644 index 000000000..17a6b1a52 --- /dev/null +++ b/test/variableTests.js @@ -0,0 +1,167 @@ +var should = require("should"); +var parser = require('./main'); + +describe('Test variables', function() { + describe('Default variables', function() { + var ast = parser.parseEval([ + '$a = "foo";', + '$b = &$c;', + '$a->b = true;' + ].join('\n')); + it('should be $a', function() { + ast.children[0].left.kind.should.be.exactly('variable'); + ast.children[0].left.name.should.be.exactly('a'); + }); + it('should be $c byref', function() { + ast.children[1].right.kind.should.be.exactly('variable'); + ast.children[1].right.name.should.be.exactly('c'); + ast.children[1].right.byref.should.be.exactly(true); + }); + it('should be $a->b', function() { + ast.children[2].left.kind.should.be.exactly('propertylookup'); + ast.children[2].left.what.kind.should.be.exactly('variable'); + ast.children[2].left.what.name.should.be.exactly('a'); + ast.children[2].left.offset.kind.should.be.exactly('constref'); + ast.children[2].left.offset.name.should.be.exactly('b'); + }); + }); + + describe('Variable chains', function() { + var ast = parser.parseEval([ + 'foo::$a[1][2];' + ].join('\n')); + it('should be $a[1][2]', function() { + var expr = ast.children[0].offset; + expr.kind.should.be.exactly('offsetlookup'); + expr.what.kind.should.be.exactly('offsetlookup'); + expr.offset.value.should.be.exactly('2'); + expr.what.what.kind.should.be.exactly('variable'); + expr.what.what.name.should.be.exactly('a'); + expr.what.offset.value.should.be.exactly('1'); + }); + }); + + describe('Class constants', function() { + var ast = parser.parseEval([ + 'static::foo();', + 'self::foo();', + 'parent::foo();', + 'foo::class;', + '$this->foo();', + 'foo::$bar;' + ].join('\n'), { + parser: { + debug: true + } + }); + it('should be static::foo', function() { + var expr = ast.children[0].what; + expr.kind.should.be.exactly('staticlookup'); + expr.what.kind.should.be.exactly('constref'); + expr.what.name.should.be.exactly('static'); + expr.offset.kind.should.be.exactly('constref'); + expr.offset.name.should.be.exactly('foo'); + }); + it('should be self::foo', function() { + var expr = ast.children[1].what; + expr.kind.should.be.exactly('staticlookup'); + // @fixme : self should be a constref + //expr.what.kind.should.be.exactly('constref'); + //expr.what.name.should.be.exactly('self'); + expr.offset.kind.should.be.exactly('constref'); + expr.offset.name.should.be.exactly('foo'); + }); + it('should be parent::foo', function() { + var expr = ast.children[2].what; + expr.kind.should.be.exactly('staticlookup'); + // @fixme : parent should be a constref + //expr.what.kind.should.be.exactly('constref'); + //expr.what.name.should.be.exactly('parent'); + expr.offset.kind.should.be.exactly('constref'); + expr.offset.name.should.be.exactly('foo'); + }); + it('should be foo::class', function() { + var expr = ast.children[3]; + expr.kind.should.be.exactly('staticlookup'); + expr.what.kind.should.be.exactly('identifier'); + expr.what.name.should.be.exactly('foo'); + expr.offset.kind.should.be.exactly('constref'); + expr.offset.name.should.be.exactly('class'); + }); + it('should be $this->foo()', function() { + var expr = ast.children[4].what; + expr.kind.should.be.exactly('propertylookup'); + expr.what.kind.should.be.exactly('variable'); + expr.what.name.should.be.exactly('this'); + expr.offset.kind.should.be.exactly('constref'); + expr.offset.name.should.be.exactly('foo'); + }); + it('should be foo::$bar', function() { + var expr = ast.children[5]; + expr.kind.should.be.exactly('staticlookup'); + expr.what.kind.should.be.exactly('identifier'); + expr.what.name.should.be.exactly('foo'); + expr.offset.kind.should.be.exactly('variable'); + expr.offset.name.should.be.exactly('bar'); + }); + }); + + + describe('Encaps var offset', function() { + var ast = parser.parseEval([ + '$a = "{$a[1]}";', + '$a = "{$a["a"]}";', + '$a = "{$a[$b]}";', + ].join('\n')); + it('should be $a[1]', function() { + //console.log(ast.children[0].right); + //ast.children[0].left.kind.should.be.exactly('variable'); + }); + }); + + describe('Dynamic variables', function() { + var ast = parser.parseEval([ + '$$a = "bar";', + '$$$a = "bar";', + '${$a."bar"} = "bar";', + '$foo{$a."bar"} = "bar";' + ].join('\n')); + it('should be $$a', function() { + ast.children[0].left.kind.should.be.exactly('variable'); + ast.children[0].left.name.kind.should.be.exactly('variable'); + ast.children[0].left.name.name.should.be.exactly('a'); + }); + it('should be $$$a', function() { + ast.children[1].left.kind.should.be.exactly('variable'); + ast.children[1].left.name.kind.should.be.exactly('variable'); + ast.children[1].left.name.name.kind.should.be.exactly('variable'); + }); + it('should be ${$a."bar"}', function() { + ast.children[2].left.kind.should.be.exactly('variable'); + ast.children[2].left.name.kind.should.be.exactly('bin'); + ast.children[2].left.name.type.should.be.exactly('.'); + ast.children[2].left.name.left.kind.should.be.exactly('variable'); + ast.children[2].left.name.left.name.should.be.exactly('a'); + ast.children[2].left.name.right.kind.should.be.exactly('string'); + ast.children[2].left.name.right.value.should.be.exactly('bar'); + }); + it('should be $foo{$a."bar"}', function() { + //console.log(ast.children[3]); + //ast.children[3].kind.should.be.exactly('variable'); + }); + }); + + describe('Check errors', function() { + var ast = parser.parseEval([ + '$? = true;' + ].join('\n'), { + parser: { + suppressErrors: true + } + }); + it('should be ?', function() { + ast.children[0].left.kind.should.be.exactly('variable'); + ast.children[0].left.name.should.be.exactly('?'); + }); + }); +});