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..d06b87f68 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ php-parser ========== -Parse PHP code from NodeJS and convert it to AST. This library is a standalone module of a larger project named [Glayzzle](http://glayzzle.com). +This javascript library parses PHP code and convert it to AST. [![npm version](https://badge.fury.io/js/php-parser.svg)](https://www.npmjs.com/package/php-parser) [![Build Status](https://travis-ci.org/glayzzle/php-parser.svg)](https://travis-ci.org/glayzzle/php-parser) @@ -9,81 +9,99 @@ Parse PHP code from NodeJS and convert it to AST. This library is a standalone m [![Gitter](https://img.shields.io/badge/GITTER-join%20chat-green.svg)](https://gitter.im/glayzzle/Lobby) -# Install it +Installation +------------ -```sh -$ npm install php-parser --save -``` - -# Try it +This library is distributed with [npm](https://www.npmjs.com/package/php-parser) : ```sh -$ cd bin -$ node test.js -e "echo 'Hello World';" +npm install php-parser --save ``` -Will output : +Usage +----- + ```js -*** START TESTING *** +// initialize the php parser factory class +var engine = require('php-parser'); +// initialize a new parser instance +var parser = new engine({ + // some options : + parser: { + extractDoc: true + }, + ast: { + withPositions: true + } +}); + +// Retrieve the AST from the specified source +var AST = parser.parseEval('echo "Hello World";'); +// AST.kind === 'program'; +// AST.children[0].kind === 'echo'; --- TOKENS : -T_ECHO T_CONSTANT_ENCAPSED_STRING ; +// Retrieve an array of tokens (same as php function token_get_all) +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 -``` - -If you run into problems with a test, run it with the cli and add the `--debug` flag. +> You can add here your own project by opening an issue request. # Misc This library is released under BSD-3 license clause. + +If you want to contribute please visit this repository https://github.com/glayzzle/php-parser-dev. diff --git a/RELEASE.md b/RELEASE.md index d5640771b..fb9d9dcc2 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,5 +1,14 @@ # Releases +## 1.0.0 : (2017-01-03) + +- 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..44121b807 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 - 2017-01-03 */ 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 0) { @@ -1452,27 +3131,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; @@ -1568,6 +3247,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( @@ -1579,10 +3261,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(); @@ -1592,6 +3272,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; }; @@ -1624,13 +3309,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') { @@ -1645,6 +3333,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; }; @@ -1667,13 +3368,20 @@ lexer.prototype.next = function () { module.exports = lexer; -},{"./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(require,module,exports){ +},{"./lexer/comments.js":95,"./lexer/initial.js":96,"./lexer/numbers.js":97,"./lexer/property.js":98,"./lexer/scripting.js":99,"./lexer/strings.js":100,"./lexer/tokens.js":101,"./lexer/utils.js":102}],95:[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 single line comment + * @see + */ T_COMMENT: function() { while(this.offset < this.size) { var ch = this.input(); @@ -1684,7 +3392,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; @@ -1717,7 +3425,7 @@ module.exports = { } }; -},{}],42:[function(require,module,exports){ +},{}],96:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -1777,7 +3485,7 @@ module.exports = { } }; -},{}],43:[function(require,module,exports){ +},{}],97:[function(require,module,exports){ (function (process){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) @@ -1785,14 +3493,16 @@ module.exports = { * @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"; } @@ -1857,8 +3567,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; } @@ -1902,7 +3614,7 @@ module.exports = { }; }).call(this,require('_process')) -},{"_process":1}],44:[function(require,module,exports){ +},{"_process":1}],98:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -1914,13 +3626,17 @@ module.exports = { if (ch === '-') { ch = this.input(); if (ch === '>') { + // https://github.com/php/php-src/blob/master/Zend/zend_language_scanner.l#L1296 return this.tok.T_OBJECT_OPERATOR; } this.unput(1); } else if (this.is_LABEL_START()) { + // https://github.com/php/php-src/blob/master/Zend/zend_language_scanner.l#L1300 this.consume_LABEL(); + this.popState(); return this.tok.T_STRING; } + // https://github.com/php/php-src/blob/master/Zend/zend_language_scanner.l#L1306 this.popState(); this.unput(1); return false; @@ -1976,7 +3692,7 @@ module.exports = { } }; -},{}],45:[function(require,module,exports){ +},{}],99:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -2078,7 +3794,7 @@ module.exports = { } }; -},{}],46:[function(require,module,exports){ +},{}],100:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -2215,6 +3931,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; @@ -2355,9 +4072,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 @@ -2480,6 +4197,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; } @@ -2492,7 +4210,7 @@ module.exports = { } }; -},{}],47:[function(require,module,exports){ +},{}],101:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -2763,7 +4481,7 @@ module.exports = { } }; -},{}],48:[function(require,module,exports){ +},{}],102:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -2818,11 +4536,6 @@ module.exports = { var ch = this._input[this.offset - 1]; return tokens.indexOf(ch) !== -1; }, - // check if current char is a newline - is_NEWLINE: function() { - var ch = this._input[this.offset - 1]; - return ch === '\n' || ch === '\r'; - }, // check if current char is a whitespace is_WHITESPACE: function() { var ch = this._input[this.offset - 1]; @@ -2851,7 +4564,7 @@ module.exports = { } }; -},{}],49:[function(require,module,exports){ +},{}],103:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -2867,37 +4580,39 @@ function isNumber(n) { /** - * The PHP Parser class - * - * @public @constructor {Parser} - * @property {Integer} EOF - * @property {Lexer} lexer - * @property {Integer|String} token - * @property {Boolean} extractDoc - * @property {Boolean} debug + * The PHP Parser class that build the AST tree from the lexer + * @constructor {Parser} + * @property {Lexer} lexer - current lexer instance + * @property {AST} ast - the AST factory instance + * @property {Integer|String} token - current token + * @property {Boolean} extractDoc - should extract documentation as AST node + * @property {Boolean} suppressErrors - should ignore parsing errors and continue + * @property {Boolean} debug - should output debug informations */ var parser = function(lexer, ast) { this.lexer = lexer; this.ast = ast; this.tok = lexer.tok; this.EOF = lexer.EOF; - // Private vars, do not use directly - this._gracefulProxy = {}; - this._graceful = false; this.token = null; this.prev = null; this.debug = false; this.extractDoc = false; this.suppressErrors = false; - this.lastError = false; - this.startAt = []; this.entries = { + 'VARIABLE': [ + this.tok.T_VARIABLE, + '$', '&', + this.tok.T_NS_SEPARATOR, + this.tok.T_STRING, + this.tok.T_NAMESPACE, + this.tok.T_STATIC + ], '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, @@ -2931,13 +4646,6 @@ var parser = function(lexer, ast) { 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, @@ -3009,8 +4717,9 @@ parser.prototype.getTokenName = function(token) { /** * main entry point : converts a source code to AST */ -parser.prototype.parse = function(code) { +parser.prototype.parse = function(code, filename) { this._errors = []; + this.filename = filename || 'eval'; this.currentNamespace = ['']; this.lexer.setInput(code); this.lexer.comment_tokens = this.extractDoc; @@ -3036,8 +4745,15 @@ 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); + var err = new SyntaxError( + message, this.filename, this.lexer.yylloc.first_line + ); + err.lineNumber = this.lexer.yylloc.first_line; + err.fileName = this.filename; + err.columnNumber = this.lexer.yylloc.first_column + throw err; } // Error node : var node = this.ast.prepare('error', this)( @@ -3072,7 +4788,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 @@ -3088,6 +4804,7 @@ parser.prototype.node = function(name) { /** * expects an end of statement or end of file + * @return {boolean} */ parser.prototype.expectEndOfStatement = function() { if (this.token === ';') { @@ -3100,8 +4817,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 **/ @@ -3144,7 +4862,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) { @@ -3157,7 +4875,7 @@ parser.prototype.expect = function(token) { this.error(token); return false; } - return this; + return true; }; /** @@ -3201,67 +4919,24 @@ parser.prototype.nextWithComments = function() { this.token = this.lexer.lex() || this.EOF; if (this.debug) this.showlog(); return this; -}; - -/** - * Check if token is of specified type - */ -parser.prototype.is = function(type) { - if (Array.isArray(type)) { - return type.indexOf(this.token) !== -1; - } else { - return this.entries[type].indexOf(this.token) != -1; - } -}; - -/** convert an token to ast **/ -parser.prototype.read_token = function() { - var result = this.token; - if (isNumber(result)) { - result = [result, this.text(), this.lexer.yylloc.first_line]; - } - this.next(); - 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); +/** + * Check if token is of specified type + */ +parser.prototype.is = function(type) { + if (Array.isArray(type)) { + return type.indexOf(this.token) !== -1; } 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 this.entries[type].indexOf(this.token) != -1; } - 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'), @@ -3272,7 +4947,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) { @@ -3282,7 +4957,7 @@ parser.prototype.read_list = function(item, separator, preserveFirstSeparator) { module.exports = parser; -},{"./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(require,module,exports){ +},{"./parser/array.js":104,"./parser/class.js":105,"./parser/comment.js":106,"./parser/expr.js":107,"./parser/function.js":108,"./parser/if.js":109,"./parser/loops.js":110,"./parser/main.js":111,"./parser/namespace.js":112,"./parser/scalar.js":113,"./parser/statement.js":114,"./parser/switch.js":115,"./parser/try.js":116,"./parser/utils.js":117,"./parser/variable.js":118}],104:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -3305,11 +4980,14 @@ module.exports = { var items = []; var result = this.node(ArrayExpr); - if (this.expect([this.tok.T_ARRAY, '[']).token == this.tok.T_ARRAY) { + if (this.token === this.tok.T_ARRAY) { this.next().expect('('); + expect = ')'; } else { shortForm = true; + expect = ']'; } + if (this.next().token != expect) { while(this.token != this.EOF) { items.push(this.read_array_pair_list()); @@ -3321,7 +4999,8 @@ module.exports = { } else break; } } - this.expect(shortForm ? ']' : ')').next(); + this.expect(expect); + this.next(); return result(shortForm, items); }, /** @@ -3369,7 +5048,7 @@ module.exports = { } }; -},{}],51:[function(require,module,exports){ +},{}],105:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -3385,29 +5064,27 @@ 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 = false - , propImplements = false + , propExtends = null + , 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(); } + this.expect('{'); + body = this.nextWithComments().read_class_body(); return result( propName - ,flag ,propExtends ,propImplements - ,this.expect('{').nextWithComments().read_class_body() + ,body + ,flag ); } /** @@ -3420,12 +5097,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 @@ -3462,7 +5139,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; } @@ -3477,13 +5155,9 @@ module.exports = { // reads a variable var variables = this.read_variable_list(flags); - this.expect(';').nextWithComments(); - - for(var i = 0; i < variables.length; i++) { - var variable = variables[i]; - (this.locations ? variable[3] : variable).push(flags); - result.push(variable); - } + this.expect(';'); + this.nextWithComments(); + result = result.concat(variables); } else if (this.token === this.tok.T_FUNCTION) { @@ -3493,18 +5167,18 @@ module.exports = { } else { // raise an error - result.push( - this.error([ - this.tok.T_CONST, - this.tok.T_VARIABLE, - this.tok.T_FUNCTION - ]) - ); - this.next(); // ignore token + this.error([ + this.tok.T_CONST, + this.tok.T_VARIABLE, + this.tok.T_FUNCTION + ]); + // ignore token + this.next(); } } - this.expect('}').nextWithComments(); + this.expect('}'); + this.nextWithComments(); return result; } /** @@ -3513,32 +5187,32 @@ module.exports = { * variable_list ::= (variable_declaration ',')* variable_declaration * ``` */ - ,read_variable_list: function() { + ,read_variable_list: function(flags) { return this.read_list( - this.read_variable_declaration, - ',' + /** + * Reads a variable declaration + * + * ```ebnf + * variable_declaration ::= T_VARIABLE '=' scalar + * ``` + */ + function read_variable_declaration() { + var result = this.node('property'); + this.expect(this.tok.T_VARIABLE); + var name = this.text(); + this.next(); + if (this.token === ';' || this.token === ',') { + return result(name, null, flags); + } else if(this.token === '=') { + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L815 + return result(name, this.next().read_expr(), flags); + } else { + this.expect([',', ';', '=']); + return result(name, null, flags); + } + }, ',' ); } - /** - * Reads a variable declaration - * ```ebnf - * variable_declaration ::= T_VARIABLE '=' scalar - * ``` - */ - ,read_variable_declaration: function() { - var result = this.node('var'); - var name = this.expect(this.tok.T_VARIABLE).text(); - this.next(); - if (this.token === ';' || this.token === ',') { - return result(name, null); - } else if(this.token === '=') { - // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L815 - return result(name, this.next().read_expr()); - } else { - this.expect([',', ';', '=']); - return result(name, null); - } - } /** * Reads constant list * ```ebnf @@ -3546,9 +5220,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 * @@ -3558,9 +5233,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); }, ',' ) @@ -3614,29 +5294,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 @@ -3650,12 +5326,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; } @@ -3665,28 +5341,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; } /** @@ -3696,28 +5376,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 ); } /** @@ -3728,26 +5411,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 @@ -3756,136 +5444,188 @@ 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); } }; -},{}],52:[function(require,module,exports){ +},{}],106:[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){ +},{}],107:[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 = { 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; } @@ -3897,114 +5637,145 @@ 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 node = this.node('parenthesis'); + var expr = this.next().read_expr(); + this.expect(')') && this.next(); + expr = node(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; + } + } - 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: @@ -4033,28 +5804,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')( @@ -4067,7 +5842,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(); } @@ -4081,20 +5858,23 @@ module.exports = { // T_YIELD (expr (T_DOUBLE_ARROW expr)?)? case this.tok.T_YIELD: - var result = ['yield', null, null]; + var result = this.node('yield'), value = null, key = null; if (this.next().is('EXPR')) { // reads the yield return value - result[1] = this.read_expr(); + value = this.read_expr(); if (this.token === this.tok.T_DOUBLE_ARROW) { // reads the yield returned key - result[2] = this.next().read_expr(); + key = value; + value = this.next().read_expr(); } } - return result; + return result(value, key); // T_YIELD_FROM expr case this.tok.T_YIELD_FROM: - return ['yieldfrom', this.next().read_expr()]; + var result = this.node('yieldfrom'); + var expr = this.next().read_expr(); + return result(expr); case this.tok.T_FUNCTION: // @fixme later - removed static lambda function declarations (colides with static keyword usage) @@ -4105,11 +5885,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) { @@ -4120,40 +5900,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(); @@ -4171,7 +5962,7 @@ module.exports = { } } } else { - expr = this.error('EXPR'); + this.error('EXPR'); this.next(); } @@ -4188,22 +5979,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 @@ -4222,12 +6017,14 @@ module.exports = { * ``` */ ,read_class_name_reference: function() { - if (this.token === '\\' || this.token === this.tok.T_STRING) { + if ( + this.token === this.tok.T_NS_SEPARATOR || + this.token === this.tok.T_STRING || + this.token === this.tok.T_NAMESPACE + ) { 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')) { @@ -4266,7 +6063,7 @@ module.exports = { } }; -},{}],54:[function(require,module,exports){ +},{}],108:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -4301,18 +6098,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,27 +6131,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 @@ -4402,34 +6212,55 @@ 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 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(); + var wasVariadic = false; + this.expect('(') && this.next(); if (this.token !== ')') { while(this.token != this.EOF) { - result.push(this.read_argument_list()); + var argument = this.read_argument_list(); + result.push(argument); + if (argument.kind === 'variadic') { + wasVariadic = true; + } else if (wasVariadic) { + this.raiseError('Unexpected argument after a variadic argument'); + } if (this.token === ',') { this.next(); } else break; } } - this.expect(')').next(); + this.expect(')') && this.next(); return result; } /** @@ -4450,23 +6281,25 @@ 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; } } }; -},{}],55:[function(require,module,exports){ +},{}],109:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -4475,207 +6308,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){ +},{}],110:[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 === '[' || this.token === this.tok.T_ARRAY) { + return this.read_array(); } else { return this.read_variable(false, false, false); } } }; -},{}],57:[function(require,module,exports){ +},{}],111:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -4697,33 +6581,33 @@ module.exports = { } }; -},{}],58:[function(require,module,exports){ +},{}],112:[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 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; @@ -4732,12 +6616,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(['{', ';']); @@ -4750,110 +6635,123 @@ 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'), 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 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), + 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; } }; -},{}],59:[function(require,module,exports){ +},{}],113:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -4905,20 +6803,10 @@ module.exports = { case this.tok.T_CONSTANT_ENCAPSED_STRING: var value = this.node('string'); var text = this.text(); - var isDoubleQuote = false; - var isBinCast = value[0] === 'b' || value[0] === 'B'; - if (isBinCast) { - isDoubleQuote = text[1] === '"'; - text = text.substring(2, text.length - 1); - } else { - isDoubleQuote = text[0] === '"'; - text = text.substring(1, text.length - 1); - } - value = value(isDoubleQuote, this.resolve_special_chars(text)); - if (isBinCast) { - value = ['cast', 'binary', value]; - } + var isDoubleQuote = text[0] === '"'; + text = text.substring(1, text.length - 1); this.next(); + value = value(isDoubleQuote, this.resolve_special_chars(text)); 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); @@ -4927,48 +6815,49 @@ module.exports = { return value; } case this.tok.T_START_HEREDOC: - return this.next().read_encapsed_string( - this.tok.T_END_HEREDOC - ); + if (this.lexer.curCondition === 'ST_NOWDOC') { + var node = this.node('nowdoc'); + var value = this.next().text(); + // strip the last line return char + var lastCh = value[value.length-1]; + if (lastCh === '\n') { + if (value[value.length-2] === '\r') { + // windows style + value = value.substring(0, value.length - 2); + } else { + // linux style + value = value.substring(0, value.length - 1); + } + } else if (lastCh === '\r') { + // mac style + value = value.substring(0, value.length - 1); + } + this.expect(this.tok.T_ENCAPSED_AND_WHITESPACE) && this.next(); + node = node(value, this.lexer.heredoc_label); + this.expect(this.tok.T_END_HEREDOC) && this.next(); + return node; + } else { + 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('"')]; + var node = this.node('cast'); + var what = this.next().read_encapsed_string('"'); + return node('binary', what); // NUMERIC - case '-': // long case this.tok.T_LNUMBER: // long case this.tok.T_DNUMBER: // double var result = this.node('number'); var value = this.text(); - if (this.token === '-') { - this.next().expect([ - this.tok.T_LNUMBER, this.tok.T_DNUMBER - ]); - value += this.text(); - } - result = result(value); this.next(); - return result; - - // CONSTANTS - case this.tok.T_NAMESPACE: - case this.tok.T_NS_SEPARATOR: - case this.tok.T_STRING: - var value = this.read_namespace_name(); - 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(); - } - // CONSTANT ARRAYS OFFSET : MYCONST[1][0]... - while(this.token === '[') { - result = ['offset', result, this.next().read_expr()]; - this.expect(']').next(); - } + result = result(value); return result; // ARRAYS @@ -4988,83 +6877,136 @@ 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; } /** + * Reads and extracts an encapsed 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 '}' + * | variable + * | variable '[' expr ']' + * | variable T_OBJECT_OPERATOR T_STRING * ``` + * @return {String|Variable|Expr|Lookup} + * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1219 */ ,read_encapsed_string_item: function() { - var result = null; + var result = this.node(); + + // plain text + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1222 if (this.token === this.tok.T_ENCAPSED_AND_WHITESPACE) { - result = this.node('string')(false, this.text()); + var text = this.text(); this.next(); - } else if (this.token === this.tok.T_DOLLAR_OPEN_CURLY_BRACES) { + result = result( + 'string', false, this.resolve_special_chars(text) + ); + } + + // dynamic variable name + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1239 + else if (this.token === this.tok.T_DOLLAR_OPEN_CURLY_BRACES) { + var name = null; 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 varName = this.text().substring(1); + name = this.node('variable'); + this.next(); + name = name(varName, false); + // check if lookup an offset + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1243 + if (this.token === '[') { + var node = this.node('offsetlookup'); + var offset = this.next().read_expr(); + this.expect(']') && this.next(); + name = node(name, offset); } } else { - result = this.read_expr(); + name = this.read_expr(); } - this.expect('}').next(); - } else if (this.token === this.tok.T_CURLY_OPEN) { + this.expect('}') && this.next(); + result = result('variable', name, false); + } + + // expression + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1246 + else if (this.token === this.tok.T_CURLY_OPEN) { result = this.next().read_variable(false, false, false); - this.expect('}').next(); - } else if (this.token === '[') { - result = ['offset', result, this.next().read_expr()]; - this.expect(']').next(); - } else if (this.token === this.tok.T_VARIABLE) { - result = this.read_variable(false, true, false); + this.expect('}') && this.next(); + } + + // plain variable + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1231 + else if (this.token === this.tok.T_VARIABLE) { + result = this.read_simple_variable(false); + + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1233 + if (this.token === '[') { + var node = this.node('offsetlookup'); + var offset = this.next().read_encaps_var_offset(); + this.expect(']') && this.next(); + result = node(result, offset); + } + + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1236 + if (this.token === this.tok.T_OBJECT_OPERATOR) { + var node = this.node('propertylookup'); + var what = this.node('constref'); + this.next().expect(this.tok.T_STRING); + var name = this.text(); + this.next(); + result = node(result, what(name)); + } + + // error / fallback } else { - this.expect([ - this.tok.T_VARIABLE, - this.tok.T_CURLY_OPEN, - this.tok.T_DOLLAR_OPEN_CURLY_BRACES, - this.tok.T_ENCAPSED_AND_WHITESPACE - ]) + this.expect(this.tok.T_ENCAPSED_AND_WHITESPACE); + var value = this.text(); + this.next(); + // consider it as string + result = result('string', false, value); } + return result; } /** * Reads an encapsed string */ ,read_encapsed_string: function(expect) { - if (this.token === expect) { - this.next(); - return null; // empty + var node = this.node('encapsed'), value = [], type = null; + + if (expect === '`') { + type = this.ast.encapsed.TYPE_SHELL; + } else if (expect === '"') { + type = this.ast.encapsed.TYPE_STRING; + } else { + type = this.ast.encapsed.TYPE_HEREDOC; } - var first = this.read_encapsed_string_item(); - if (this.token === expect) { - this.next(); - return first; - } - var result = [ - 'bin', '.' - , first - , this.read_encapsed_string_item() - ]; - while(this.token !== expect) { - result[3] = [ - 'bin', '.', result[3], this.read_encapsed_string_item() - ]; + + // reading encapsed parts + while(this.token !== expect && this.token !== this.EOF) { + value.push(this.read_encapsed_string_item()); } - this.expect(expect).next(); - return result; + + this.expect(expect) && this.next(); + node = node(value, type); + + if (expect === this.tok.T_END_HEREDOC) { + node.label = this.lexer.heredoc_label; + } + return node; } /** * Constant token @@ -5077,7 +7019,7 @@ module.exports = { } }; -},{}],60:[function(require,module,exports){ +},{}],114:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -5117,38 +7059,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 @@ -5188,8 +7127,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; @@ -5197,16 +7140,24 @@ module.exports = { /** * Reads a list of constants declaration * ```ebnf - * const_list ::= T_CONST T_STRING '=' expr (',' T_STRING '=' expr)* + * declare_list ::= T_STRING '=' expr (',' T_STRING '=' expr)* * ``` + * @retrurn {Object} */ ,read_declare_list: function() { - return this.read_list(function() { + var result = {}; + while(this.token != this.EOF && this.token !== ')') { this.expect(this.tok.T_STRING); - var name = this.text(); - this.next().expect('=').next(); - return [name, this.read_expr()]; - }, ','); + var name = this.text().toLowerCase(); + if (this.next().expect('=')) { + result[name] = this.next().read_expr(); + } else { + result[name] = null; + } + if (this.token !== ',') break; + this.next(); + } + return result; } /** * reads a simple inner statement @@ -5217,31 +7168,38 @@ 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(); - this.raiseError('__HALT_COMPILER() can only be used from the outermost scope'); + this.raiseError( + '__HALT_COMPILER() can only be used from the outermost scope' + ); + // fallback : returns a node but does not stop the parsing + var node = this.node('halt'); + this.next().expect('(') && this.next(); + this.expect(')') && this.next(); + node = node(this.lexer._input.substring( + this.lexer.offset + )); + this.expect(';') && this.next(); + return node; default: return this.read_statement(); } @@ -5272,25 +7230,31 @@ 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); + + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L429 + case this.tok.T_BREAK: + case this.tok.T_CONTINUE: + var result = this.node( + this.token === this.tok.T_CONTINUE ? 'continue' : 'break' + ), level = null; + this.next(); // look ahead + if (this.token !== ';' && this.token !== this.tok.T_CLOSE_TAG) { + level = this.read_expr(); + } + this.expectEndOfStatement(); + return result(level); 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()]; @@ -5299,28 +7263,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 === '=') { - value = this.next().read_expr(); - } - return [name, value]; - }, ','); + var items = this.read_variable_declarations(); this.expectEndOfStatement(); - return result('declare', items); + return result(items); case this.tok.T_ECHO: var result = this.node('echo'); - var withParanthesis = (this.next().token === '('); - withParanthesis && this.next(); - var args = this.read_list(this.read_expr, ','); - if (withParanthesis) { - this.expect(')').next(); - } + var args = this.next().read_list(this.read_expr, ','); this.expectEndOfStatement(); return result(args); @@ -5331,33 +7283,46 @@ 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(); - options = this.read_declare_list(); - this.expect(')').nextWithComments(); + var result = this.node('declare'), + what, + body = [], + mode; + this.next().expect('(') && this.next(); + what = this.read_declare_list(); + this.expect(')') && this.next(); if (this.token === ':') { - body = []; - this.next(); + this.nextWithComments(); while(this.token != this.EOF && this.token !== this.tok.T_ENDDECLARE) { - body.push(this.read_statement()); + // @todo : check declare_statement from php / not valid + body.push(this.read_top_statement()); } - this.ignoreComments().expect(this.tok.T_ENDDECLARE).next().expectEndOfStatement(); + this.expect(this.tok.T_ENDDECLARE) && this.next(); + this.expectEndOfStatement(); + mode = this.ast.declare.MODE_SHORT; + } else if (this.token === '{') { + this.nextWithComments(); + while(this.token != this.EOF && this.token !== '}') { + // @todo : check declare_statement from php / not valid + body.push(this.read_top_statement()); + } + this.expect('}') && this.next(); + mode = this.ast.declare.MODE_BLOCK; } else { - body = this.read_statement(); + this.expect(';') && this.next(); + while(this.token != this.EOF && this.token !== this.tok.T_DECLARE) { + // @todo : check declare_statement from php / not valid + body.push(this.read_top_statement()); + } + mode = this.ast.declare.MODE_NONE; } - return result(options, body); - break; + return result(what, body, mode); case this.tok.T_TRY: return this.read_try(); @@ -5384,14 +7349,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 +7373,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){ +},{}],115:[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 +7430,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 +7440,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 +7455,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){ +},{}],116:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -5520,52 +7495,177 @@ 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); } }; -},{}],63:[function(require,module,exports){ +},{}],117:[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()); + } 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(); @@ -5701,15 +7817,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; @@ -5726,21 +7845,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; } /** @@ -5757,17 +7884,20 @@ 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 == '[') { + var offset = null; if (encapsed) { - result = this.next().read_encaps_var_offset(); + offset = this.next().read_encaps_var_offset(); } else { - var offset = this.next().token === ']' ? null : this.read_dim_offset(); - result = ['offset', result, offset]; + offset = this.next().token === ']' ? null : this.read_dim_offset(); } - this.expect(']').next(); + this.expect(']') && this.next(); + result = node('offsetlookup', result, offset); } 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; @@ -5779,36 +7909,42 @@ 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; } }; -},{}],64:[function(require,module,exports){ +},{}],119:[function(require,module,exports){ /*! * Copyright (C) 2017 Glayzzle (BSD3 License) * @authors https://github.com/glayzzle/php-parser/graphs/contributors @@ -6126,8 +8262,33 @@ function combine(src, to) { } /** + * Initialise a new parser instance with the specified options + * + * Usage : + * ```js + * var parser = require('php-parser'); + * var instance = new parser({ + * parser: { + * extractDoc: true, + * suppressErrors: true + * }, + * ast: { + * withPositions: true + * }, + * lexer: { + * short_tags: true, + * asp_tags: true + * } + * }); + * + * var evalAST = instance.parseEval('some php code'); + * var codeAST = instance.parseCode(' Note that the output tokens are *STRICLY* similar to PHP function `token_get_all` + * @param {String} buffer + * @return {String[]} - Each item can be a string or an array with following informations [token_name, text, line_number] */ engine.prototype.tokenGetAll = function(buffer) { this.lexer.mode_eval = false; @@ -6223,4 +8414,4 @@ engine.prototype.tokenGetAll = function(buffer) { // exports the function module.exports = engine; -},{"./ast":2,"./lexer":40,"./parser":49,"./tokens":64}]},{},[]); +},{"./ast":2,"./lexer":94,"./parser":103,"./tokens":119}]},{},[]); diff --git a/dist/php-parser.min.js b/dist/php-parser.min.js index 88e321660..ad7c8a5d6 100644 --- a/dist/php-parser.min.js +++ b/dist/php-parser.min.js @@ -1,78 +1,93 @@ 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.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, -"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] -}};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", -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}]},{},[]); +2:[function(a,b,c){var d=a("./ast/location"),e=a("./ast/position"),f=function(a,b){this.withPositions=a,this.withSource=b};f.prototype.position=function(a){return new e(a.lexer.yylloc.first_line,a.lexer.yylloc.first_column,a.lexer.yylloc.first_offset)},f.prototype.prepare=function(a,b){var c=null;(this.withPositions||this.withSource)&&(c=this.position(b));var f=this;return function(){var g=null,h=Array.prototype.slice.call(arguments);if(f.withPositions||f.withSource){var i=null;f.withSource&&(i=b.lexer._input.substring(c.offset,b.lexer.yylloc.prev_offset)),g=f.withPositions?new d(i,c,new e(b.lexer.yylloc.prev_line,b.lexer.yylloc.prev_column,b.lexer.yylloc.prev_offset)):new d(i,null,null),h.push(g)}a||(a=h.shift());var j=f[a];if("function"!=typeof j)throw new Error('Undefined node "'+a+'"');var k=Object.create(j.prototype);return j.apply(k,h),k}},[a("./ast/array"),a("./ast/assign"),a("./ast/bin"),a("./ast/block"),a("./ast/bool"),a("./ast/boolean"),a("./ast/break"),a("./ast/call"),a("./ast/case"),a("./ast/cast"),a("./ast/catch"),a("./ast/class"),a("./ast/classconstant"),a("./ast/clone"),a("./ast/closure"),a("./ast/coalesce"),a("./ast/constant"),a("./ast/constref"),a("./ast/continue"),a("./ast/declare"),a("./ast/do"),a("./ast/doc"),a("./ast/echo"),a("./ast/empty"),a("./ast/encapsed"),a("./ast/entry"),a("./ast/error"),a("./ast/eval"),a("./ast/exit"),a("./ast/expression"),a("./ast/for"),a("./ast/foreach"),a("./ast/function"),a("./ast/global"),a("./ast/goto"),a("./ast/halt"),a("./ast/identifier"),a("./ast/if"),a("./ast/include"),a("./ast/inline"),a("./ast/interface"),a("./ast/isset"),a("./ast/label"),a("./ast/list"),a("./ast/literal"),a("./ast/magic"),a("./ast/method"),a("./ast/namespace"),a("./ast/new"),a("./ast/node"),a("./ast/nowdoc"),a("./ast/number"),a("./ast/offsetlookup"),a("./ast/parameter"),a("./ast/parenthesis"),a("./ast/post"),a("./ast/pre"),a("./ast/print"),a("./ast/program"),a("./ast/property"),a("./ast/propertylookup"),a("./ast/retif"),a("./ast/return"),a("./ast/shell"),a("./ast/silent"),a("./ast/static"),a("./ast/staticlookup"),a("./ast/string"),a("./ast/switch"),a("./ast/throw"),a("./ast/trait"),a("./ast/traitalias"),a("./ast/traitprecedence"),a("./ast/traituse"),a("./ast/try"),a("./ast/unary"),a("./ast/unset"),a("./ast/usegroup"),a("./ast/useitem"),a("./ast/variable"),a("./ast/variadic"),a("./ast/while"),a("./ast/yield"),a("./ast/yieldfrom")].forEach(function(a){ +var b=a.prototype.constructor.name.toLowerCase();"_"===b[0]&&(b=b.substring(1)),f.prototype[b]=a}),b.exports=f},{"./ast/array":3,"./ast/assign":4,"./ast/bin":5,"./ast/block":6,"./ast/bool":7,"./ast/boolean":8,"./ast/break":9,"./ast/call":10,"./ast/case":11,"./ast/cast":12,"./ast/catch":13,"./ast/class":14,"./ast/classconstant":15,"./ast/clone":16,"./ast/closure":17,"./ast/coalesce":18,"./ast/constant":19,"./ast/constref":20,"./ast/continue":21,"./ast/declare":23,"./ast/do":24,"./ast/doc":25,"./ast/echo":26,"./ast/empty":27,"./ast/encapsed":28,"./ast/entry":29,"./ast/error":30,"./ast/eval":31,"./ast/exit":32,"./ast/expression":33,"./ast/for":34,"./ast/foreach":35,"./ast/function":36,"./ast/global":37,"./ast/goto":38,"./ast/halt":39,"./ast/identifier":40,"./ast/if":41,"./ast/include":42,"./ast/inline":43,"./ast/interface":44,"./ast/isset":45,"./ast/label":46,"./ast/list":47,"./ast/literal":48,"./ast/location":49,"./ast/magic":51,"./ast/method":52,"./ast/namespace":53,"./ast/new":54,"./ast/node":55,"./ast/nowdoc":56, +"./ast/number":57,"./ast/offsetlookup":58,"./ast/parameter":60,"./ast/parenthesis":61,"./ast/position":62,"./ast/post":63,"./ast/pre":64,"./ast/print":65,"./ast/program":66,"./ast/property":67,"./ast/propertylookup":68,"./ast/retif":69,"./ast/return":70,"./ast/shell":71,"./ast/silent":72,"./ast/static":74,"./ast/staticlookup":75,"./ast/string":76,"./ast/switch":77,"./ast/throw":79,"./ast/trait":80,"./ast/traitalias":81,"./ast/traitprecedence":82,"./ast/traituse":83,"./ast/try":84,"./ast/unary":85,"./ast/unset":86,"./ast/usegroup":87,"./ast/useitem":88,"./ast/variable":89,"./ast/variadic":90,"./ast/while":91,"./ast/yield":92,"./ast/yieldfrom":93}],3:[function(a,b,c){var d=a("./expression"),e="array",f=d.extends(function(a,b,c){d.apply(this,[e,c]),this.items=b,this.shortForm=a});b.exports=f},{"./expression":33}],4:[function(a,b,c){var d=a("./statement"),e="assign",f=d.extends(function(a,b,c,f){d.apply(this,[e,f]),this.operator=c,this.left=a,this.right=b});b.exports=f},{"./statement":73}],5:[function(a,b,c){"use strict"; +var d=a("./operation"),e="bin",f={"+":1,"-":1,".":1,"*":2,"/":2,"%":2},g=d.extends(function(a,b,c,g){if(d.apply(this,[e,g]),c&&"bin"===c.kind){var h=f[a],i=f[c.type];if(h&&i&&i=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.yylloc.last_column--,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;if(this._input||(this.done=!0),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.done)return this.yylloc.prev_offset=this.yylloc.first_offset,this.yylloc.prev_line=this.yylloc.first_line,this.yylloc.prev_column=this.yylloc.first_column,this.EOF;if(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),this.debug){var b=a;b="number"==typeof b?this.engine.tokens.values[b]:'"'+b+'"',console.log(b,"from "+this.yylloc.first_line+","+this.yylloc.first_column," - to "+this.yylloc.last_line+","+this.yylloc.last_column)}return 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":95,"./lexer/initial.js":96,"./lexer/numbers.js":97,"./lexer/property.js":98,"./lexer/scripting.js":99,"./lexer/strings.js":100,"./lexer/tokens.js":101,"./lexer/utils.js":102}],95:[function(a,b,c){"use strict";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), +this.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.offset"===a)return this.tok.T_OBJECT_OPERATOR;this.unput(1)}else if(this.is_LABEL_START())return this.consume_LABEL(),this.popState(),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")}}},{}],99:[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}}},{}],101:[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):"^"}}}},{}],102:[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}}},{}],103:[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.token=null,this.prev=null,this.debug=!1,this.extractDoc=!1,this.suppressErrors=!1,this.entries={VARIABLE:[this.tok.T_VARIABLE,"$","&",this.tok.T_NS_SEPARATOR,this.tok.T_STRING,this.tok.T_NAMESPACE,this.tok.T_STATIC],SCALAR:[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,'"','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],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,b){this._errors=[],this.filename=b||"eval",this.currentNamespace=[""],this.lexer.setInput(a),this.lexer.comment_tokens=this.extractDoc,this.length=this.lexer._input.length,this.innerList=!1;var c=this.ast.prepare("program",this),d=[];for(this.nextWithComments();this.token!=this.EOF;){var e=this.read_start();null!==e&&void 0!==e&&(Array.isArray(e)?d=d.concat(e):d.push(e))}return c(d,this._errors)},e.prototype.raiseError=function(a,b,c,d){if(a+=" on line "+this.lexer.yylloc.first_line,!this.suppressErrors){var e=new SyntaxError(a,this.filename,this.lexer.yylloc.first_line);throw e.lineNumber=this.lexer.yylloc.first_line,e.fileName=this.filename,e.columnNumber=this.lexer.yylloc.first_column,e}var f=this.ast.prepare("error",this)(a,d,this.lexer.yylloc.first_line,c);return this._errors.push(f),f},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,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},[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":104,"./parser/class.js":105,"./parser/comment.js":106,"./parser/expr.js":107,"./parser/function.js":108,"./parser/if.js":109,"./parser/loops.js":110,"./parser/main.js":111,"./parser/namespace.js":112,"./parser/scalar.js":113,"./parser/statement.js":114,"./parser/switch.js":115,"./parser/try.js":116,"./parser/utils.js":117,"./parser/variable.js":118}],104:[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.token===this.tok.T_ARRAY?(this.next().expect("("),a=")"):(b=!0,a="]"),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(a),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()}}},{}],105:[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)}}},{}],106:[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>",b,this.next().read_expr());if(this.token===this.tok.T_BOOLEAN_OR)return a("bool","|",b,this.next().read_expr());if(this.token===this.tok.T_LOGICAL_OR)return a("bool","|",b,this.next().read_expr());if(this.token===this.tok.T_BOOLEAN_AND)return a("bool","&",b,this.next().read_expr());if(this.token===this.tok.T_LOGICAL_AND)return a("bool","&",b,this.next().read_expr());if(this.token===this.tok.T_LOGICAL_XOR)return a("bool","^",b,this.next().read_expr());if(this.token===this.tok.T_IS_IDENTICAL)return a("bool","=",b,this.next().read_expr());if(this.token===this.tok.T_IS_NOT_IDENTICAL)return a("bool","!=",b,this.next().read_expr());if(this.token===this.tok.T_IS_EQUAL)return a("bool","~",b,this.next().read_expr());if(this.token===this.tok.T_IS_NOT_EQUAL)return a("bool","!~",b,this.next().read_expr());if("<"===this.token)return a("bool","<",b,this.next().read_expr()); +if(">"===this.token)return a("bool","!~",b,this.next().read_expr());if(this.token===this.tok.T_IS_SMALLER_OR_EQUAL)return a("bool","<=",b,this.next().read_expr());if(this.token===this.tok.T_IS_GREATER_OR_EQUAL)return a("bool","=>",b,this.next().read_expr());if(this.token===this.tok.T_SPACESHIP)return a("bool","<=>",b,this.next().read_expr());if(this.token===this.tok.T_INSTANCEOF)return a("bool","?",b,this.next().read_expr());if(this.token===this.tok.T_COALESCE)return a("coalesce",b,this.next().read_expr());if("?"===this.token){var c=null;return":"!==this.next().token&&(c=this.read_expr()),this.expect(":")&&this.next(),a("retif",b,c,this.read_expr())}return b},read_expr_item:function(){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 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())}if("("===this.token){var b=this.node("parenthesis"),c=this.next().read_expr();return this.expect(")")&&this.next(),c=b(c),this.token===this.tok.T_OBJECT_OPERATOR?this.recursive_variable_chain_scan(c,!1):this.token===this.tok.T_CURLY_OPEN||"["===this.token?this.read_dereferencable(c):"("===this.token?this.node("call")(c,this.read_function_argument_list()):c}if("`"===this.token)return this.node("shell")(this.next().read_encapsed_string("`"));if(this.token===this.tok.T_LIST){var a=this.node("list"),d=null,e=this.innerList;e||(d=this.node("assign")),this.next().expect("(")&&this.next(),this.innerList||(this.innerList=!0);for(var f=this.read_assignment_list(),g=!1,h=0;h>=");case this.tok.T_INC:return this.next(),a("post","+",c);case this.tok.T_DEC:return this.next(),a("post","-",c)}}else if(this.is("SCALAR"))for(c=this.read_scalar();this.token!==this.EOF;)if(this.token===this.tok.T_OBJECT_OPERATOR)c=this.recursive_variable_chain_scan(c,!1);else if(this.token===this.tok.T_CURLY_OPEN||"["===this.token)c=this.read_dereferencable(c);else{if("("!==this.token)return c;c=this.node("call")(c,this.read_function_argument_list())}else this.error("EXPR"),this.next();return c},read_new_expr:function(){var a=this.node("new");if(this.token===this.tok.T_CLASS){var b=this.node("class"),c=null,d=null,e=null; +return this.next().token==this.tok.T_EXTENDS&&(c=this.next().read_namespace_name()),this.token==this.tok.T_IMPLEMENTS&&(d=this.next().read_name_list()),this.expect("{")&&(e=this.next().read_class_body()),a(b(null,c,d,e,[0,0,0]),[])}var f=this.read_class_name_reference(),g=[];return"("===this.token&&(g=this.read_function_argument_list()),a(f,g)},read_class_name_reference:function(){if(this.token===this.tok.T_NS_SEPARATOR||this.token===this.tok.T_STRING||this.token===this.tok.T_NAMESPACE){var a=this.read_namespace_name();return this.token===this.tok.T_DOUBLE_COLON&&(a=this.read_static_getter(a)),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}}},{}],108:[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=null,h=!1;1!==a&&this.expect(this.tok.T_STRING)&&(e=this.text(),this.next()),this.expect("(")&&this.next();var i=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&&("?"===this.next().token&&(h=!0,this.next()),g=this.read_type()),1===a?c(i,d,f,g,h):c(e,i,d,g,h)}, +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=null,e=!1;"?"===this.token&&(this.next(),e=!0),d=this.read_type(),e&&!d&&this.raiseError("Expecting a type definition combined with nullable operator");var f=this.is_reference(),g=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,f,g,e)},read_function_argument_list:function(){var a=[],b=!1;if(this.expect("(")&&this.next(),")"!==this.token)for(;this.token!=this.EOF;){var c=this.read_argument_list();if(a.push(c),"variadic"===c.kind?b=!0:b&&this.raiseError("Unexpected argument after a variadic argument"), +","!==this.token)break;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(){var a=this.node("identifier");switch(this.token){case this.tok.T_ARRAY:return this.next(),a(["","array"],!1);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:return this.next(),a(["","callable"],!1);default:return null}}}},{}],109:[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)}}},{}],110:[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.token===this.tok.T_ARRAY?this.read_array():this.read_variable(!1,!1,!1)}}},{}],111:[function(a,b,c){b.exports={read_start:function(){return this.token==this.tok.T_NAMESPACE?this.read_namespace():this.read_top_statement()}}},{}],112:[function(a,b,c){"use strict";b.exports={read_namespace:function(){var a=this.node("namespace");if(this.expect(this.tok.T_NAMESPACE)&&this.next(),"{"==this.token)return this.currentNamespace=[""],a([""],this.read_code_block(!0),!0); +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),!0);if("("===this.token)return b.resolution=this.ast.identifier.RELATIVE_NAME,b.name=b.name.substring(1),this.node("call")(b,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"),b=!1;return this.token===this.tok.T_NAMESPACE&&(this.next().expect(this.tok.T_NS_SEPARATOR)&&this.next(),b=!0),a(this.read_list(this.tok.T_STRING,this.tok.T_NS_SEPARATOR,!0),b)},read_use_statement:function(){var a=this.node("usegroup"),b=null,c=[],d=null;return this.expect(this.tok.T_USE)&&this.next(),b=this.read_use_type(),c.push(this.read_use_declaration(!1)),","===this.token?c=c.concat(this.next().read_use_declarations(!1)):"{"===this.token&&(d=c[0].name, +c=this.next().read_use_declarations(null===b),this.expect("}")&&this.next()),this.expect(";")&&this.nextWithComments(),a(d,b,c)},read_use_declaration:function(a){var b=this.node("useitem"),c=null;a&&(c=this.read_use_type());var d=this.read_namespace_name(),e=this.read_use_alias();return b(d,e,c)},read_use_declarations:function(a){for(var b=[this.read_use_declaration(a)];","===this.token;)b.push(this.next().read_use_declaration(a));return b},read_use_alias:function(){var a=null;return this.token===this.tok.T_AS&&this.next().expect(this.tok.T_STRING)&&(a=this.text(),this.next()),a},read_use_type:function(){return this.token===this.tok.T_FUNCTION?(this.next(),this.ast.useitem.TYPE_FUNCTION):this.token===this.tok.T_CONST?(this.next(),this.ast.useitem.TYPE_CONST):null}}},{}],113:[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='"'===b[0];return b=b.substring(1,b.length-1),this.next(),a=a(c,this.resolve_special_chars(b)),this.token===this.tok.T_DOUBLE_COLON?this.read_static_getter(a):a;case this.tok.T_START_HEREDOC:if("ST_NOWDOC"===this.lexer.curCondition){var d=this.node("nowdoc"),a=this.next().text(),e=a[a.length-1];return"\n"===e?a="\r"===a[a.length-2]?a.substring(0,a.length-2):a.substring(0,a.length-1):"\r"===e&&(a=a.substring(0,a.length-1)),this.expect(this.tok.T_ENCAPSED_AND_WHITESPACE)&&this.next(),d=d(a,this.lexer.heredoc_label),this.expect(this.tok.T_END_HEREDOC)&&this.next(),d}return this.next().read_encapsed_string(this.tok.T_END_HEREDOC);case'"':return this.next().read_encapsed_string('"');case'b"':case'B"':var d=this.node("cast"),f=this.next().read_encapsed_string('"');return d("binary",f);case this.tok.T_LNUMBER:case this.tok.T_DNUMBER: +var g=this.node("number"),a=this.text();return this.next(),g=g(a);case this.tok.T_ARRAY:case"[":return this.read_array();default:var h=this.error("SCALAR");return this.next(),h}},read_dereferencable:function(a){var b,c=this.node("offsetlookup");if("["===this.token){var d=this.next().read_expr();this.expect("]")&&this.next(),b=c(a,d)}else if(this.token===this.tok.T_DOLLAR_OPEN_CURLY_BRACES){var d=this.read_encapsed_string_item();b=c(a,d)}return b},read_encapsed_string_item:function(){var a=this.node();if(this.token===this.tok.T_ENCAPSED_AND_WHITESPACE){var b=this.text();this.next(),a=a("string",!1,this.resolve_special_chars(b))}else if(this.token===this.tok.T_DOLLAR_OPEN_CURLY_BRACES){var c=null;if(this.next().token===this.tok.T_STRING_VARNAME){var d=this.text().substring(1);if(c=this.node("variable"),this.next(),c=c(d,!1),"["===this.token){var e=this.node("offsetlookup"),f=this.next().read_expr();this.expect("]")&&this.next(),c=e(c,f)}}else c=this.read_expr();this.expect("}")&&this.next(),a=a("variable",c,!1)}else if(this.token===this.tok.T_CURLY_OPEN)a=this.next().read_variable(!1,!1,!1), +this.expect("}")&&this.next();else if(this.token===this.tok.T_VARIABLE){if(a=this.read_simple_variable(!1),"["===this.token){var e=this.node("offsetlookup"),f=this.next().read_encaps_var_offset();this.expect("]")&&this.next(),a=e(a,f)}if(this.token===this.tok.T_OBJECT_OPERATOR){var e=this.node("propertylookup"),g=this.node("constref");this.next().expect(this.tok.T_STRING);var c=this.text();this.next(),a=e(a,g(c))}}else{this.expect(this.tok.T_ENCAPSED_AND_WHITESPACE);var h=this.text();this.next(),a=a("string",!1,h)}return a},read_encapsed_string:function(a){var b=this.node("encapsed"),c=[],d=null;for(d="`"===a?this.ast.encapsed.TYPE_SHELL:'"'===a?this.ast.encapsed.TYPE_STRING:this.ast.encapsed.TYPE_HEREDOC;this.token!==a&&this.token!==this.EOF;)c.push(this.read_encapsed_string_item());return this.expect(a)&&this.next(),b=b(c,d),a===this.tok.T_END_HEREDOC&&(b.label=this.lexer.heredoc_label),b},get_magic_constant:function(){var a=this.node("magic"),b=this.text();return this.next(),a(b)}}},{}],114:[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: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 b=this.node("halt");return this.next().expect("(")&&this.next(),this.expect(")")&&this.next(),this.expect(";"),this.lexer.done=!0,b(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(){for(var a={};this.token!=this.EOF&&")"!==this.token;){this.expect(this.tok.T_STRING);var b=this.text().toLowerCase();if(this.next().expect("=")?a[b]=this.next().read_expr():a[b]=null,","!==this.token)break;this.next()}return a},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.raiseError("__HALT_COMPILER() can only be used from the outermost scope");var b=this.node("halt");return this.next().expect("(")&&this.next(),this.expect(")")&&this.next(),b=b(this.lexer._input.substring(this.lexer.offset)),this.expect(";")&&this.next(),b;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:case this.tok.T_CONTINUE:var a=this.node(this.token===this.tok.T_CONTINUE?"continue":"break"),c=null;return this.next(),";"!==this.token&&this.token!==this.tok.T_CLOSE_TAG&&(c=this.read_expr()),this.expectEndOfStatement(),a(c);case this.tok.T_GLOBAL:var a=this.node("global"),d=this.next().read_list(this.read_simple_variable,",");return this.expectEndOfStatement(),a(d);case this.tok.T_STATIC:var e=[this.token,this.lexer.getState()],a=this.node("static");if(this.next().token===this.tok.T_DOUBLE_COLON){this.lexer.tokens.push(e);var b=this.next().read_expr();return this.expect(";")&&this.nextWithComments(),b}var d=this.read_variable_declarations();return this.expectEndOfStatement(),a(d);case this.tok.T_ECHO:var a=this.node("echo"),f=this.next().read_list(this.read_expr,",");return 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 d=this.read_list(this.read_variable,",");return this.expect(")")&&this.next(),this.expect(";")&&this.nextWithComments(),a(d);case this.tok.T_DECLARE:var g,h,a=this.node("declare"),i=[];if(this.next().expect("(")&&this.next(),g=this.read_declare_list(),this.expect(")")&&this.next(),":"===this.token){for(this.nextWithComments();this.token!=this.EOF&&this.token!==this.tok.T_ENDDECLARE;)i.push(this.read_top_statement());this.expect(this.tok.T_ENDDECLARE)&&this.next(),this.expectEndOfStatement(),h=this.ast.declare.MODE_SHORT}else if("{"===this.token){for(this.nextWithComments();this.token!=this.EOF&&"}"!==this.token;)i.push(this.read_top_statement());this.expect("}")&&this.next(),h=this.ast.declare.MODE_BLOCK}else{for(this.expect(";")&&this.next();this.token!=this.EOF&&this.token!==this.tok.T_DECLARE;)i.push(this.read_top_statement());h=this.ast.declare.MODE_NONE}return a(g,i,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 e=[this.token,this.lexer.getState()],j=this.text();if(":"===this.next().token){var a=this.node("label");return this.next(),a(j)}this.lexer.tokens.push(e);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"),j=null;return this.next().expect(this.tok.T_STRING)&&(j=this.text(),this.next().expectEndOfStatement()),a(j);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)}}},{}],115:[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)}}},{}],116:[function(a,b,c){b.exports={read_try:function(){this.expect(this.tok.T_TRY);var a,b=this.node("try"),c=null,d=[]; +for(a=this.nextWithComments().read_statement(),this.ignoreComments();this.token===this.tok.T_CATCH;){var e=this.node("catch"),f=[],g=null;this.next().expect("(")&&this.next(),f=this.read_list(this.read_namespace_name,"|",!1),g=this.read_variable(!0,!1,!1),this.expect(")"),d.push(e(this.next().read_statement(),f,g)),this.ignoreComments()}return this.token===this.tok.T_FINALLY&&(c=this.nextWithComments().read_statement()),b(a,d,c)}}},{}],117:[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{if(!this.expect(a))return[];for(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)},read_variable_declarations:function(){return this.read_list(function(){var a=this.node("assign"),b=this.node("variable");if(this.expect(this.tok.T_VARIABLE)){var c=this.text().substring(1);this.next(),b=b(c,!1)}else b=b("#ERR",!1);return"="===this.token?a(b,this.next().read_expr()):b},",")}}},{}],118:[function(a,b,c){"use strict";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,this.tok.T_NAMESPACE])){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?(d=this.node("constref"),this.next(),d=d("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=this.node("staticlookup"),d=null;if(this.next().is([this.tok.T_VARIABLE,"$"]))d=this.read_reference_variable(b,!1);else if(this.token===this.tok.T_STRING||this.token===this.tok.T_CLASS){d=this.node("constref");var e=this.text();this.next(),d=d(e)}else{this.error([this.tok.T_VARIABLE,this.tok.T_STRING]),d=this.node("constref");var e=this.text();this.next(),d=d(e)}return c(a,d)},recursive_variable_chain_scan:function(a,b,c){a:for(;this.token!=this.EOF;)switch(this.token){case"(":if(b)return a;a=this.node("call")(a,this.read_function_argument_list());break;case"[":var d=this.node("offsetlookup");this.next();var e=!1;c?(e=this.read_encaps_var_offset(),this.expect("]")&&this.next()):"]"!==this.token?(e=this.read_expr(),this.expect("]")&&this.next()):this.next(),a=d(a,e);break;case this.tok.T_OBJECT_OPERATOR:var d=this.node("propertylookup"),f=null;switch(this.next().token){case this.tok.T_STRING:f=this.node("constref");var g=this.text(); +this.next(),f=f(g),this.token===this.tok.T_VARIABLE?(g=this.text().substring(1),this.next(),f=["bin",".",f,["var",g]]):"{"===this.token&&(f=["bin",".",f,this.next().read_expr()],this.expect("}")&&this.next());break;case this.tok.T_VARIABLE:f=this.node("variable");var g=this.text().substring(1);this.next(),f=f(g,!1);break;case"$":this.next().expect(["{",this.tok.T_VARIABLE]),"{"===this.token?(f=this.next().read_expr(),this.expect("}")&&this.next()):f=this.read_expr();break;case"{":f=this.next().read_expr(),this.expect("}")&&this.next();break;default:this.error([this.tok.T_STRING,this.tok.T_VARIABLE]),f=this.node("constref");var g=this.text();this.next(),f=f(g)}a=d(a,f);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),this.next(),a=a("string",c,this.resolve_special_chars(b))}else if(this.token===this.tok.T_NUM_STRING){var d=this.text();this.next(),a=a("number",d)}else if(this.token===this.tok.T_VARIABLE){ +var e=this.text().substring(1);this.next(),a=a("variable",e,!1)}else{this.expect([this.tok.T_STRING,this.tok.T_NUM_STRING,this.tok.T_VARIABLE]);var b=this.text();this.next(),a=a("string",!1,b)}return a},read_reference_variable:function(a,b){for(var c=this.read_simple_variable(b);this.token!=this.EOF;){var d=this.node();if("["==this.token){var e=null;e=a?this.next().read_encaps_var_offset():"]"===this.next().token?null:this.read_dim_offset(),this.expect("]")&&this.next(),c=d("offsetlookup",c,e)}else{if("{"!=this.token||a)break;var e=this.next().read_expr();this.expect("}")&&this.next(),c=d("offsetlookup",c,e)}}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){var c=this.text().substring(1);this.next(),b=b(c,a)}else switch("$"===this.token&&this.next(),this.token){case"{":var d=this.next().read_expr();this.expect("}")&&this.next(),b=b(d,a);break;case"$":b=b(this.read_simple_variable(!1),a);break;case this.tok.T_VARIABLE: +var c=this.text().substring(1),e=this.node("variable");this.next(),b=b(e(c,!1),a);break;default:this.error(["{","$",this.tok.T_VARIABLE]);var c=this.text();this.next(),b=b(c,a)}return b}}},{}],119:[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,"eval")},i.parseCode=function(a,b,c){"object"==typeof b&&(c=b,b="unknown");var d=new i(c);return d.parseCode(a,b)},i.prototype.parseCode=function(a,b){return this.lexer.mode_eval=!1,this.lexer.all_tokens=!1,this.parser.parse(a,b)},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":94,"./parser":103,"./tokens":119}]},{},[]); //# 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..c58264710 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":"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","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","position","parser","lexer","yylloc","first_line","first_column","first_offset","prepare","kind","start","self","location","slice","src","_input","substring","offset","prev_offset","prev_line","prev_column","shift","node","result","Object","create","forEach","ctor","constructor","toLowerCase","./ast/array","./ast/assign","./ast/bin","./ast/block","./ast/bool","./ast/boolean","./ast/break","./ast/call","./ast/case","./ast/cast","./ast/catch","./ast/class","./ast/classconstant","./ast/clone","./ast/closure","./ast/coalesce","./ast/constant","./ast/constref","./ast/continue","./ast/declare","./ast/do","./ast/doc","./ast/echo","./ast/empty","./ast/encapsed","./ast/entry","./ast/error","./ast/eval","./ast/exit","./ast/expression","./ast/for","./ast/foreach","./ast/function","./ast/global","./ast/goto","./ast/halt","./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/new","./ast/node","./ast/nowdoc","./ast/number","./ast/offsetlookup","./ast/parameter","./ast/parenthesis","./ast/position","./ast/post","./ast/pre","./ast/print","./ast/program","./ast/property","./ast/propertylookup","./ast/retif","./ast/return","./ast/shell","./ast/silent","./ast/static","./ast/staticlookup","./ast/string","./ast/switch","./ast/throw","./ast/trait","./ast/traitalias","./ast/traitprecedence","./ast/traituse","./ast/try","./ast/unary","./ast/unset","./ast/usegroup","./ast/useitem","./ast/variable","./ast/variadic","./ast/while","./ast/yield","./ast/yieldfrom","3","Expr","KIND","extends","shortForm","items","./expression","4","Statement","Assign","left","right","operator","./statement","5","Operation","precedence","+","-",".","*","/","%","Bin","type","lLevel","rLevel","buffer","./operation","6","Block","children","7","Bool","8","Literal","Boolean","value","./literal","9","Node","Break","level","./node","10","Call","what","11","Case","test","body","12","Cast","13","Catch","variable","14","Declaration","Class","ext","impl","flags","isAnonymous","implements","parseFlags","./declaration","15","Constant","ClassConstant","./constant","16","Clone","17","Closure","byref","nullable","18","Coalesce","ifnull","19","20","ConstRef","identifier","21","Continue","22","IS_PUBLIC","IS_PROTECTED","IS_PRIVATE","isAbstract","isFinal","visibility","isStatic","23","Declare","mode","MODE_SHORT","MODE_BLOCK","MODE_NONE","./block","24","Do","25","Doc","isDoc","lines","26","Sys","Echo","./sys","27","Empty","28","Encapsed","TYPE_STRING","TYPE_SHELL","TYPE_HEREDOC","29","Entry","key","30","message","token","line","expected","31","Eval","source","32","Exit","status","33","Expression","34","For","init","increment","35","Foreach","36","fn","37","Global","38","Goto","label","39","Halt","after","40","Identifier","isRelative","resolution","RELATIVE_NAME","UNQUALIFIED_NAME","FULL_QUALIFIED_NAME","QUALIFIED_NAME","join","41","If","alternate","42","Include","target","43","Inline","44","Interface","45","Isset","46","Label","47","List","48","49","end","50","Lookup","51","Magic","52","Method","./function","53","Namespace","withBrackets","./identifier","54","New","55","loc","56","Nowdoc","57","_Number","58","OffsetLookup","./lookup","59","60","Parameter","isRef","isVariadic","variadic","61","Parenthesis","inner","62","column","63","Post","64","Pre","65","Print","66","Program","errors","67","Property","68","PropertyLookup","69","RetIf","trueExpr","falseExpr","70","Return","expr","71","Shell","72","Silent","73","74","Static","75","StaticLookup","76","String","isDoubleQuote","77","Switch","78","79","Throw","80","Trait","81","TraitAlias","trait","method","as","82","TraitPrecedence","instead","83","TraitUse","traits","adaptations","84","Try","catches","always","85","Unary","86","Unset","87","UseGroup","88","UseItem","alias","TYPE_CONST","TYPE_FUNCTION","89","Variable","90","Variadic","91","While","92","Yield","93","YieldFrom","94","engine","tok","tokens","names","EOF","debug","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","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","tName","values","console","log","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","95","aspTagMode","is_WHITESPACE","96","nextINITIAL","matchINITIAL","T_INLINE_HTML","97","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","98","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","99","matchST_IN_SCRIPTING","consume_TOKEN","T_CONSTANT_ENCAPSED_STRING","ST_DOUBLE_QUOTES","nextCH","T_CLOSE_TAG","100","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","101","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","102","charCodeAt","indexOf","103","isNumber","isNaN","parseFloat","isFinite","ast","prev","extractDoc","suppressErrors","entries","VARIABLE","SCALAR","T_MAGIC_CONST","T_MEMBER_FLAGS","EOS","EXPR","getTokenName","parse","filename","_errors","currentNamespace","innerList","program","childs","nextWithComments","read_start","undefined","isArray","raiseError","msgExpect","expect","err","SyntaxError","lineNumber","fileName","columnNumber","error","msg","symbol","expectEndOfStatement","ignoreStack","showlog","stack","split","trim","found","ignoreComments","is","./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","104","ArrayExpr","ArrayEntry","read_array","read_array_pair_list","read_variable","read_expr","read_dim_offset","105","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","106","docSplit","107","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","108","is_reference","is_variadic","closure","read_code_block","nodeName","returnType","params","read_parameter_list","read_lexical_var","read_type","read_parameter","wasVariadic","argument","read_argument_list","109","read_if","read_if_expr","read_elseif_short","read_else_short","read_inner_statement","read_statement","110","read_while","read_short_form","read_do","read_for","read_foreach","read_foreach_variable","111","read_namespace","read_top_statement","112","read_top_statements","relative","read_use_statement","read_use_type","read_use_declaration","read_use_declarations","typed","read_use_alias","useitem","113","specialChar","\\r","\\n","\\t","\\v","fromCharCode","\\e","\\f","\\\\","\\$","\\\"","\\'","resolve_special_chars","replace","seq","get_magic_constant","lastCh","read_encapsed_string_item","varName","read_simple_variable","read_encaps_var_offset","encapsed","114","statement","read_const_list","read_inner_statements","read_declare_list","read_switch","current","read_variable_declarations","read_try","top","115","read_switch_case_list","read_case_list","stopToken","116","item","117","separator","preserveFirstSeparator","118","read_only","read_reference_variable","literal","recursive_scan_loop","isDblQuote","num","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","options","parseEval","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..d7b4bea1d 100644 --- a/docs/AST.md +++ b/docs/AST.md @@ -4,8 +4,38 @@ ## 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) + - [Variadic](#variadic) + - [ConstRef](#constref) + - [Yield](#yield) + - [YieldFrom](#yieldfrom) + - [Lookup](#lookup) + - [PropertyLookup](#propertylookup) + - [StaticLookup](#staticlookup) + - [OffsetLookup](#offsetlookup) + - [Operation](#operation) + - [Coalesce](#coalesce) + - [Pre](#pre) + - [Post](#post) + - [Bin](#bin) + - [Parenthesis](#parenthesis) + - [Bool](#Bool) + - [Unary](#unary) + - [Cast](#cast) - [Literal](#literal) - [Boolean](#boolean) - [String](#string) @@ -13,38 +43,55 @@ - [Inline](#inline) - [Magic](#magic) - [Shell](#shell) - - [Array](#array) - - [Variable](#variable) + - [Nowdoc](#nowdoc) + - [Encapsed](#encapsed) - [Statement](#statement) + - [Eval](#eval) + - [Exit](#exit) + - [Halt](#halt) + - [Clone](#clone) + - [Declare](#declare) + - [Global](#global) + - [Static](#static) + - [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) + - [Throw](#throw) + - [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 +100,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 +138,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 +185,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 +207,90 @@ 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 + +**Properties** + +- `level` **([Number](#number) \| [Null](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null))** + +# 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 +305,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 +327,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 +363,26 @@ 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 + +**Properties** + +- `level` **([Number](#number) \| [Null](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null))** + # Declaration **Extends Statement** @@ -209,6 +403,70 @@ Generic flags parser Returns **void** +# Declare + +**Extends Block** + +The declare construct is used to set execution directives for a block of code + +**Properties** + +- `what` **[Array](#array)<[Expression](#expression)>** +- `mode` **[String](#string)** + +## MODE_SHORT + +The node is declared as a short tag syntax : + +```php +** # Echo @@ -232,6 +490,53 @@ Defines system based call Defines an empty check call +# Encapsed + +**Extends Literal** + +Defines an encapsed string (contains expressions) + +**Properties** + +- `type` **[String](#string)** Defines the type of encapsed string (shell, heredoc, string) +- `label` **([String](#string) \| [Null](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null))** The heredoc label, defined only when the type is heredoc + +## TYPE_STRING + +The node is a double quote string : + +```php +** +- `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 +624,41 @@ 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)** + +# Halt + +**Extends Statement** + +Halts the compiler execution + +**Properties** + +- `after` **[String](#string)** String after the halt statement # Identifier @@ -305,7 +669,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 +728,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 +787,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 +828,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 @@ -411,12 +863,44 @@ Helper for extending the Node class Returns **[Function](#function)** +# String + +**Extends Literal** + +Defines a nowdoc string + +**Properties** + +- `label` **[String](#string)** + +# String + +**Extends Literal** + +Defines a string (simple ou double quoted) - chars are already escaped + +**Properties** + +- `isDoubleQuote` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** + # Number **Extends Literal** 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 +913,17 @@ 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)** + +# Parenthesis + +**Extends Operation** + +Parenthesis encapsulation `(... expr ...)` + +**Properties** + +- `inner` **[Expression](#expression)** # Position @@ -446,6 +941,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,27 +992,83 @@ 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. -# String +# Static -**Extends Literal** +**Extends Statement** -Defines inline html output (treated as echo output) +Declares a static variable into the current scope **Properties** -- `isDoubleQuote` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** +- `items` **([Array](#array)<[Variable](#variable)> | [Array](#array)<[Assign](#assign)>)** + +# StaticLookup + +**Extends Lookup** + +Lookup to a static property + +# 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 @@ -507,12 +1080,117 @@ Defines system based call - `arguments` **[Array](#array)<[Node](#node)>** +# Throw + +**Extends Statement** + +Defines a throw statement + +**Properties** + +- `what` **[Expression](#expression)** + +# 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 +1200,48 @@ 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)** + +# Variadic + +**Extends Expression** + +Introduce a list of items into the arguments of the call + +**Properties** + +- `what` **([Array](#array) \| [Expression](#expression))** + +# 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)** + +# Yield + +**Extends Expression** + +Defines a yield generator statement + +**Properties** + +- `value` **([Expression](#expression) \| [Null](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null))** +- `key` **([Expression](#expression) \| [Null](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null))** + +# YieldFrom + +**Extends Expression** + +Defines a yield from generator statement + +**Properties** + +- `value` **[Expression](#expression)** diff --git a/docs/README.md b/docs/README.md index 5bf4e18da..f63f080cf 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,1302 +2,89 @@ # engine +Initialise a new parser instance with the specified options + +Usage : + +```js +var parser = require('php-parser'); +var instance = new parser({ + parser: { + extractDoc: true, + suppressErrors: true + }, + ast: { + withPositions: true + }, + lexer: { + short_tags: true, + asp_tags: true + } +}); + +var evalAST = instance.parseEval('some php code'); +var codeAST = instance.parseCode(' - -# 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 +Extract tokens from the specified buffer. -convert an token to ast \* - -## read_list - -Helper : reads a list of tokens / sample : T_STRING ',' T_STRING ... - -```ebnf -list ::= separator? ( item separator )* item -``` +> Note that the output tokens are _STRICLY_ similar to PHP function `token_get_all` **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** +- `buffer` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** -- `identifier` **([String](#string) \| [Node](#node))** -- `byref` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** +Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)<[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)>** Each item can be a string or an array with following informations [token_name, text, line_number] diff --git a/docs/lexer.md b/docs/lexer.md index 50c7c5905..6b6ef50f8 100644 --- a/docs/lexer.md +++ b/docs/lexer.md @@ -56,6 +56,10 @@ Sets the current lexer state - `state` +# T_COMMENT + +Reads a single line comment + # T_DOC_COMMENT Behaviour : diff --git a/docs/parser.md b/docs/parser.md index eeab64eb3..e1edbd75a 100644 --- a/docs/parser.md +++ b/docs/parser.md @@ -2,7 +2,9 @@ # parser -The PHP Parser class +The PHP Parser class that build the AST tree from the lexer + +Type: Parser **Parameters** @@ -11,11 +13,12 @@ The PHP Parser class **Properties** -- `EOF` **Integer** -- `lexer` **Lexer** -- `token` **(Integer | [String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String))** -- `extractDoc` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** -- `debug` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** +- `lexer` **Lexer** current lexer instance +- `ast` **AST** the AST factory instance +- `token` **(Integer | [String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String))** current token +- `extractDoc` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** should extract documentation as AST node +- `suppressErrors` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** should ignore parsing errors and continue +- `debug` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** should output debug informations ## getTokenName @@ -32,6 +35,7 @@ main entry point : converts a source code to AST **Parameters** - `code` +- `filename` ## raiseError @@ -64,6 +68,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 +87,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 @@ -109,24 +115,6 @@ Check if token is of specified type - `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 \* @@ -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_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) '}' +';' ``` -# read_inline_use_declaration +Returns **UseGroup** + +# read_use_declaration + +Reads a use declaration ```ebnf - inline_use_declaration ::= ... +use_declaration ::= use_type? namespace_name use_alias ``` -# read_use_statement_mixed +Returns **UseItem** + +# read_use_declarations + +Reads a list of use declarations ```ebnf - use_statement_mixed ::= - use_statement (T_AS T_STRING | '{' read_inline_use_declaration '}' ) - (',' read_use_statement)* +use_declarations ::= use_declaration (',' use_declaration)* ``` -# read_use_statement +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 ::= ( - (T_FUNCTION | T_CONST)? namespace_name - ) +use_alias ::= (T_AS T_STRING)? ``` +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_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 @@ -485,15 +541,21 @@ Handles the dereferencing # read_encapsed_string_item +Reads and extracts an encapsed 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 '}' + | variable + | variable '[' expr ']' + | variable T_OBJECT_OPERATOR T_STRING ``` +Returns **([String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) | Variable | Expr | Lookup)** + # read_encapsed_string Reads an encapsed string @@ -543,7 +605,7 @@ Reads a list of constants declaration Reads a list of constants declaration ```ebnf - const_list ::= T_CONST T_STRING '=' expr (',' T_STRING '=' expr)* + declare_list ::= T_STRING '=' expr (',' T_STRING '=' expr)* ``` # read_inner_statement @@ -572,6 +634,8 @@ Reads a switch statement switch ::= T_SWITCH '(' expr ')' switch_case_list ``` +Returns **Switch** + # read_switch_case_list ```ebnf @@ -594,17 +658,72 @@ 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_declarations + +Reads a list of variables declarations + +```ebnf +variable_declaration ::= T_VARIABLE ('=' expr)?* +variable_declarations ::= variable_declaration (',' variable_declaration)* +``` + +Sample code : + +```php + | [Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)<Assign>)** Returns an array composed by a list of variables, or +assign values + # 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..3eedbd2d6 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,11 @@ { "name": "php-parser", "version": "1.0.0", - "description": "Parse PHP code with NodeJS and convert it to AST", + "description": "Parse PHP 5/7 code and returns its 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..01f35dc4a 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,38 @@ 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) + * - [Variadic](#variadic) + * - [ConstRef](#constref) + * - [Yield](#yield) + * - [YieldFrom](#yieldfrom) + * - [Lookup](#lookup) + * - [PropertyLookup](#propertylookup) + * - [StaticLookup](#staticlookup) + * - [OffsetLookup](#offsetlookup) + * - [Operation](#operation) + * - [Coalesce](#coalesce) + * - [Pre](#pre) + * - [Post](#post) + * - [Bin](#bin) + * - [Parenthesis](#parenthesis) + * - [Bool](#Bool) + * - [Unary](#unary) + * - [Cast](#cast) * - [Literal](#literal) * - [Boolean](#boolean) * - [String](#string) @@ -19,38 +49,55 @@ var Position = require('./ast/position'); * - [Inline](#inline) * - [Magic](#magic) * - [Shell](#shell) - * - [Array](#array) - * - [Variable](#variable) + * - [Nowdoc](#nowdoc) + * - [Encapsed](#encapsed) * - [Statement](#statement) + * - [Eval](#eval) + * - [Exit](#exit) + * - [Halt](#halt) + * - [Clone](#clone) + * - [Declare](#declare) + * - [Global](#global) + * - [Static](#static) + * - [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) + * - [Throw](#throw) + * - [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 +112,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 +136,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 +148,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 +182,88 @@ 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/declare'), + require('./ast/do'), + require('./ast/doc'), require('./ast/echo'), require('./ast/empty'), + require('./ast/encapsed'), require('./ast/entry'), require('./ast/error'), require('./ast/eval'), require('./ast/exit'), + require('./ast/expression'), + require('./ast/for'), + require('./ast/foreach'), require('./ast/function'), + require('./ast/global'), + require('./ast/goto'), + require('./ast/halt'), 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/node'), + require('./ast/nowdoc'), require('./ast/number'), + require('./ast/offsetlookup'), require('./ast/parameter'), + require('./ast/parenthesis'), + 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/static'), + require('./ast/staticlookup'), require('./ast/string'), + require('./ast/switch'), + require('./ast/throw'), + 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/variadic'), + require('./ast/while'), + require('./ast/yield'), + require('./ast/yieldfrom') ].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..96a97b0bb --- /dev/null +++ b/src/ast/bin.js @@ -0,0 +1,50 @@ +/*! + * 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'; + +// define nodes shifting +var precedence = { + '+': 1, + '-': 1, + '.': 1, + '*': 2, + '/': 2, + '%': 2 +}; + +/** + * 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]); + if (right && right.kind === 'bin') { + var lLevel = precedence[type]; + var rLevel = precedence[right.type]; + if (lLevel && rLevel && rLevel < lLevel) { + // shift precedence + var buffer = right.right; + right.right = right.left; + right.left = left; + left = buffer; + buffer = right.type; + right.type = type; + type = buffer; + } + } + 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..9efd19a5d --- /dev/null +++ b/src/ast/break.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 = 'break'; + +/** + * A break statement + * @constructor Break + * @extends {Node} + * @property {Number|Null} level + */ +var Break = Node.extends(function Break(level, location) { + Node.apply(this, [KIND, location]); + this.level = level; +}); + +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..65f2e9bff --- /dev/null +++ b/src/ast/continue.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 = 'continue'; + +/** + * A continue statement + * @constructor Continue + * @extends {Node} + * @property {Number|Null} level + */ +var Continue = Node.extends(function Continue(level, location) { + Node.apply(this, [KIND, location]); + this.level = level; +}); + +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/declare.js b/src/ast/declare.js new file mode 100644 index 000000000..0b974c6f2 --- /dev/null +++ b/src/ast/declare.js @@ -0,0 +1,64 @@ +/*! + * Copyright (C) 2017 Glayzzle (BSD3 License) + * @authors https://github.com/glayzzle/php-parser/graphs/contributors + * @url http://glayzzle.com + */ + +var Block = require('./block'); +var KIND = 'declare'; + +/** + * The declare construct is used to set execution directives for a block of code + * @constructor Declare + * @extends {Block} + * @property {Expression[]} what + * @property {String} mode + * @see http://php.net/manual/en/control-structures.declare.php + */ +var Declare = Block.extends(function Declare(what, body, mode, location) { + Block.apply(this, [KIND, body, location]); + this.what = what; + this.mode = mode; +}); + + +/** + * The node is declared as a short tag syntax : + * ```php + * Note that the output tokens are *STRICLY* similar to PHP function `token_get_all` + * @param {String} buffer + * @return {String[]} - Each item can be a string or an array with following informations [token_name, text, line_number] */ engine.prototype.tokenGetAll = function(buffer) { this.lexer.mode_eval = false; 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/property.js b/src/lexer/property.js index a17b2c04c..55b75c8b6 100644 --- a/src/lexer/property.js +++ b/src/lexer/property.js @@ -9,13 +9,17 @@ module.exports = { if (ch === '-') { ch = this.input(); if (ch === '>') { + // https://github.com/php/php-src/blob/master/Zend/zend_language_scanner.l#L1296 return this.tok.T_OBJECT_OPERATOR; } this.unput(1); } else if (this.is_LABEL_START()) { + // https://github.com/php/php-src/blob/master/Zend/zend_language_scanner.l#L1300 this.consume_LABEL(); + this.popState(); return this.tok.T_STRING; } + // https://github.com/php/php-src/blob/master/Zend/zend_language_scanner.l#L1306 this.popState(); this.unput(1); return false; 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/lexer/utils.js b/src/lexer/utils.js index eed1517b3..5d311a1d1 100644 --- a/src/lexer/utils.js +++ b/src/lexer/utils.js @@ -52,11 +52,6 @@ module.exports = { var ch = this._input[this.offset - 1]; return tokens.indexOf(ch) !== -1; }, - // check if current char is a newline - is_NEWLINE: function() { - var ch = this._input[this.offset - 1]; - return ch === '\n' || ch === '\r'; - }, // check if current char is a whitespace is_WHITESPACE: function() { var ch = this._input[this.offset - 1]; diff --git a/src/parser.js b/src/parser.js index 5aaeb4ac8..a4af965c9 100644 --- a/src/parser.js +++ b/src/parser.js @@ -13,37 +13,39 @@ function isNumber(n) { /** - * The PHP Parser class - * - * @public @constructor {Parser} - * @property {Integer} EOF - * @property {Lexer} lexer - * @property {Integer|String} token - * @property {Boolean} extractDoc - * @property {Boolean} debug + * The PHP Parser class that build the AST tree from the lexer + * @constructor {Parser} + * @property {Lexer} lexer - current lexer instance + * @property {AST} ast - the AST factory instance + * @property {Integer|String} token - current token + * @property {Boolean} extractDoc - should extract documentation as AST node + * @property {Boolean} suppressErrors - should ignore parsing errors and continue + * @property {Boolean} debug - should output debug informations */ var parser = function(lexer, ast) { this.lexer = lexer; this.ast = ast; this.tok = lexer.tok; this.EOF = lexer.EOF; - // Private vars, do not use directly - this._gracefulProxy = {}; - this._graceful = false; this.token = null; this.prev = null; this.debug = false; this.extractDoc = false; this.suppressErrors = false; - this.lastError = false; - this.startAt = []; this.entries = { + 'VARIABLE': [ + this.tok.T_VARIABLE, + '$', '&', + this.tok.T_NS_SEPARATOR, + this.tok.T_STRING, + this.tok.T_NAMESPACE, + this.tok.T_STATIC + ], '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, @@ -77,13 +79,6 @@ var parser = function(lexer, ast) { 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, @@ -155,8 +150,9 @@ parser.prototype.getTokenName = function(token) { /** * main entry point : converts a source code to AST */ -parser.prototype.parse = function(code) { +parser.prototype.parse = function(code, filename) { this._errors = []; + this.filename = filename || 'eval'; this.currentNamespace = ['']; this.lexer.setInput(code); this.lexer.comment_tokens = this.extractDoc; @@ -182,8 +178,15 @@ 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); + var err = new SyntaxError( + message, this.filename, this.lexer.yylloc.first_line + ); + err.lineNumber = this.lexer.yylloc.first_line; + err.fileName = this.filename; + err.columnNumber = this.lexer.yylloc.first_column + throw err; } // Error node : var node = this.ast.prepare('error', this)( @@ -218,7 +221,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 +237,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 +250,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 +295,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 +308,7 @@ parser.prototype.expect = function(token) { this.error(token); return false; } - return this; + return true; }; /** @@ -360,54 +365,11 @@ parser.prototype.is = function(type) { } }; -/** convert an token to ast **/ -parser.prototype.read_token = function() { - var result = this.token; - if (isNumber(result)) { - result = [result, this.text(), this.lexer.yylloc.first_line]; - } - this.next(); - 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 +380,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..f1bbd4344 100644 --- a/src/parser/array.js +++ b/src/parser/array.js @@ -20,11 +20,14 @@ module.exports = { var items = []; var result = this.node(ArrayExpr); - if (this.expect([this.tok.T_ARRAY, '[']).token == this.tok.T_ARRAY) { + if (this.token === this.tok.T_ARRAY) { this.next().expect('('); + expect = ')'; } else { shortForm = true; + expect = ']'; } + if (this.next().token != expect) { while(this.token != this.EOF) { items.push(this.read_array_pair_list()); @@ -36,7 +39,8 @@ module.exports = { } else break; } } - this.expect(shortForm ? ']' : ')').next(); + this.expect(expect); + 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..ad333d705 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,145 @@ 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 node = this.node('parenthesis'); + var expr = this.next().read_expr(); + this.expect(')') && this.next(); + expr = node(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; + } + } - 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; - } + // 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 - ); - } - 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 +261,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 +299,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(); } @@ -253,20 +315,23 @@ module.exports = { // T_YIELD (expr (T_DOUBLE_ARROW expr)?)? case this.tok.T_YIELD: - var result = ['yield', null, null]; + var result = this.node('yield'), value = null, key = null; if (this.next().is('EXPR')) { // reads the yield return value - result[1] = this.read_expr(); + value = this.read_expr(); if (this.token === this.tok.T_DOUBLE_ARROW) { // reads the yield returned key - result[2] = this.next().read_expr(); + key = value; + value = this.next().read_expr(); } } - return result; + return result(value, key); // T_YIELD_FROM expr case this.tok.T_YIELD_FROM: - return ['yieldfrom', this.next().read_expr()]; + var result = this.node('yieldfrom'); + var expr = this.next().read_expr(); + return result(expr); case this.tok.T_FUNCTION: // @fixme later - removed static lambda function declarations (colides with static keyword usage) @@ -277,11 +342,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 +357,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 +419,7 @@ module.exports = { } } } else { - expr = this.error('EXPR'); + this.error('EXPR'); this.next(); } @@ -360,22 +436,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 @@ -394,12 +474,14 @@ module.exports = { * ``` */ ,read_class_name_reference: function() { - if (this.token === '\\' || this.token === this.tok.T_STRING) { + if ( + this.token === this.tok.T_NS_SEPARATOR || + this.token === this.tok.T_STRING || + this.token === this.tok.T_NAMESPACE + ) { 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..113b83c61 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,34 +146,55 @@ 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(); + var wasVariadic = false; + this.expect('(') && this.next(); if (this.token !== ')') { while(this.token != this.EOF) { - result.push(this.read_argument_list()); + var argument = this.read_argument_list(); + result.push(argument); + if (argument.kind === 'variadic') { + wasVariadic = true; + } else if (wasVariadic) { + this.raiseError('Unexpected argument after a variadic argument'); + } if (this.token === ',') { this.next(); } else break; } } - this.expect(')').next(); + this.expect(')') && this.next(); return result; } /** @@ -177,16 +215,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..6e9662db9 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 === '[' || this.token === this.tok.T_ARRAY) { + 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..d3f729132 100644 --- a/src/parser/scalar.js +++ b/src/parser/scalar.js @@ -49,20 +49,10 @@ module.exports = { case this.tok.T_CONSTANT_ENCAPSED_STRING: var value = this.node('string'); var text = this.text(); - var isDoubleQuote = false; - var isBinCast = value[0] === 'b' || value[0] === 'B'; - if (isBinCast) { - isDoubleQuote = text[1] === '"'; - text = text.substring(2, text.length - 1); - } else { - isDoubleQuote = text[0] === '"'; - text = text.substring(1, text.length - 1); - } - value = value(isDoubleQuote, this.resolve_special_chars(text)); - if (isBinCast) { - value = ['cast', 'binary', value]; - } + var isDoubleQuote = text[0] === '"'; + text = text.substring(1, text.length - 1); this.next(); + value = value(isDoubleQuote, this.resolve_special_chars(text)); 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); @@ -71,48 +61,49 @@ module.exports = { return value; } case this.tok.T_START_HEREDOC: - return this.next().read_encapsed_string( - this.tok.T_END_HEREDOC - ); + if (this.lexer.curCondition === 'ST_NOWDOC') { + var node = this.node('nowdoc'); + var value = this.next().text(); + // strip the last line return char + var lastCh = value[value.length-1]; + if (lastCh === '\n') { + if (value[value.length-2] === '\r') { + // windows style + value = value.substring(0, value.length - 2); + } else { + // linux style + value = value.substring(0, value.length - 1); + } + } else if (lastCh === '\r') { + // mac style + value = value.substring(0, value.length - 1); + } + this.expect(this.tok.T_ENCAPSED_AND_WHITESPACE) && this.next(); + node = node(value, this.lexer.heredoc_label); + this.expect(this.tok.T_END_HEREDOC) && this.next(); + return node; + } else { + 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('"')]; + var node = this.node('cast'); + var what = this.next().read_encapsed_string('"'); + return node('binary', what); // NUMERIC - case '-': // long case this.tok.T_LNUMBER: // long case this.tok.T_DNUMBER: // double var result = this.node('number'); var value = this.text(); - if (this.token === '-') { - this.next().expect([ - this.tok.T_LNUMBER, this.tok.T_DNUMBER - ]); - value += this.text(); - } - result = result(value); this.next(); - return result; - - // CONSTANTS - case this.tok.T_NAMESPACE: - case this.tok.T_NS_SEPARATOR: - case this.tok.T_STRING: - var value = this.read_namespace_name(); - 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(); - } - // CONSTANT ARRAYS OFFSET : MYCONST[1][0]... - while(this.token === '[') { - result = ['offset', result, this.next().read_expr()]; - this.expect(']').next(); - } + result = result(value); return result; // ARRAYS @@ -132,83 +123,136 @@ 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; } /** + * Reads and extracts an encapsed 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 '}' + * | variable + * | variable '[' expr ']' + * | variable T_OBJECT_OPERATOR T_STRING * ``` + * @return {String|Variable|Expr|Lookup} + * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1219 */ ,read_encapsed_string_item: function() { - var result = null; + var result = this.node(); + + // plain text + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1222 if (this.token === this.tok.T_ENCAPSED_AND_WHITESPACE) { - result = this.node('string')(false, this.text()); + var text = this.text(); this.next(); - } else if (this.token === this.tok.T_DOLLAR_OPEN_CURLY_BRACES) { + result = result( + 'string', false, this.resolve_special_chars(text) + ); + } + + // dynamic variable name + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1239 + else if (this.token === this.tok.T_DOLLAR_OPEN_CURLY_BRACES) { + var name = null; 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 varName = this.text().substring(1); + name = this.node('variable'); + this.next(); + name = name(varName, false); + // check if lookup an offset + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1243 + if (this.token === '[') { + var node = this.node('offsetlookup'); + var offset = this.next().read_expr(); + this.expect(']') && this.next(); + name = node(name, offset); } } else { - result = this.read_expr(); + name = this.read_expr(); } - this.expect('}').next(); - } else if (this.token === this.tok.T_CURLY_OPEN) { + this.expect('}') && this.next(); + result = result('variable', name, false); + } + + // expression + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1246 + else if (this.token === this.tok.T_CURLY_OPEN) { result = this.next().read_variable(false, false, false); - this.expect('}').next(); - } else if (this.token === '[') { - result = ['offset', result, this.next().read_expr()]; - this.expect(']').next(); - } else if (this.token === this.tok.T_VARIABLE) { - result = this.read_variable(false, true, false); + this.expect('}') && this.next(); + } + + // plain variable + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1231 + else if (this.token === this.tok.T_VARIABLE) { + result = this.read_simple_variable(false); + + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1233 + if (this.token === '[') { + var node = this.node('offsetlookup'); + var offset = this.next().read_encaps_var_offset(); + this.expect(']') && this.next(); + result = node(result, offset); + } + + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1236 + if (this.token === this.tok.T_OBJECT_OPERATOR) { + var node = this.node('propertylookup'); + var what = this.node('constref'); + this.next().expect(this.tok.T_STRING); + var name = this.text(); + this.next(); + result = node(result, what(name)); + } + + // error / fallback } else { - this.expect([ - this.tok.T_VARIABLE, - this.tok.T_CURLY_OPEN, - this.tok.T_DOLLAR_OPEN_CURLY_BRACES, - this.tok.T_ENCAPSED_AND_WHITESPACE - ]) + this.expect(this.tok.T_ENCAPSED_AND_WHITESPACE); + var value = this.text(); + this.next(); + // consider it as string + result = result('string', false, value); } + return result; } /** * Reads an encapsed string */ ,read_encapsed_string: function(expect) { - if (this.token === expect) { - this.next(); - return null; // empty + var node = this.node('encapsed'), value = [], type = null; + + if (expect === '`') { + type = this.ast.encapsed.TYPE_SHELL; + } else if (expect === '"') { + type = this.ast.encapsed.TYPE_STRING; + } else { + type = this.ast.encapsed.TYPE_HEREDOC; } - var first = this.read_encapsed_string_item(); - if (this.token === expect) { - this.next(); - return first; + + // reading encapsed parts + while(this.token !== expect && this.token !== this.EOF) { + value.push(this.read_encapsed_string_item()); } - var result = [ - 'bin', '.' - , first - , this.read_encapsed_string_item() - ]; - while(this.token !== expect) { - result[3] = [ - 'bin', '.', result[3], this.read_encapsed_string_item() - ]; + + this.expect(expect) && this.next(); + node = node(value, type); + + if (expect === this.tok.T_END_HEREDOC) { + node.label = this.lexer.heredoc_label; } - this.expect(expect).next(); - return result; + return node; } /** * Constant token diff --git a/src/parser/statement.js b/src/parser/statement.js index 0a378a8b9..51702098b 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; @@ -117,16 +118,24 @@ module.exports = { /** * Reads a list of constants declaration * ```ebnf - * const_list ::= T_CONST T_STRING '=' expr (',' T_STRING '=' expr)* + * declare_list ::= T_STRING '=' expr (',' T_STRING '=' expr)* * ``` + * @retrurn {Object} */ ,read_declare_list: function() { - return this.read_list(function() { + var result = {}; + while(this.token != this.EOF && this.token !== ')') { this.expect(this.tok.T_STRING); - var name = this.text(); - this.next().expect('=').next(); - return [name, this.read_expr()]; - }, ','); + var name = this.text().toLowerCase(); + if (this.next().expect('=')) { + result[name] = this.next().read_expr(); + } else { + result[name] = null; + } + if (this.token !== ',') break; + this.next(); + } + return result; } /** * reads a simple inner statement @@ -137,31 +146,38 @@ 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(); - this.raiseError('__HALT_COMPILER() can only be used from the outermost scope'); + this.raiseError( + '__HALT_COMPILER() can only be used from the outermost scope' + ); + // fallback : returns a node but does not stop the parsing + var node = this.node('halt'); + this.next().expect('(') && this.next(); + this.expect(')') && this.next(); + node = node(this.lexer._input.substring( + this.lexer.offset + )); + this.expect(';') && this.next(); + return node; default: return this.read_statement(); } @@ -192,25 +208,31 @@ 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); + + // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L429 + case this.tok.T_BREAK: + case this.tok.T_CONTINUE: + var result = this.node( + this.token === this.tok.T_CONTINUE ? 'continue' : 'break' + ), level = null; + this.next(); // look ahead + if (this.token !== ';' && this.token !== this.tok.T_CLOSE_TAG) { + level = this.read_expr(); + } + this.expectEndOfStatement(); + return result(level); 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,28 +241,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 === '=') { - value = this.next().read_expr(); - } - return [name, value]; - }, ','); + var items = this.read_variable_declarations(); this.expectEndOfStatement(); - return result('declare', items); + return result(items); case this.tok.T_ECHO: var result = this.node('echo'); - var withParanthesis = (this.next().token === '('); - withParanthesis && this.next(); - var args = this.read_list(this.read_expr, ','); - if (withParanthesis) { - this.expect(')').next(); - } + var args = this.next().read_list(this.read_expr, ','); this.expectEndOfStatement(); return result(args); @@ -251,33 +261,46 @@ 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(); - options = this.read_declare_list(); - this.expect(')').nextWithComments(); + var result = this.node('declare'), + what, + body = [], + mode; + this.next().expect('(') && this.next(); + what = this.read_declare_list(); + this.expect(')') && this.next(); if (this.token === ':') { - body = []; - this.next(); + this.nextWithComments(); while(this.token != this.EOF && this.token !== this.tok.T_ENDDECLARE) { - body.push(this.read_statement()); + // @todo : check declare_statement from php / not valid + body.push(this.read_top_statement()); } - this.ignoreComments().expect(this.tok.T_ENDDECLARE).next().expectEndOfStatement(); + this.expect(this.tok.T_ENDDECLARE) && this.next(); + this.expectEndOfStatement(); + mode = this.ast.declare.MODE_SHORT; + } else if (this.token === '{') { + this.nextWithComments(); + while(this.token != this.EOF && this.token !== '}') { + // @todo : check declare_statement from php / not valid + body.push(this.read_top_statement()); + } + this.expect('}') && this.next(); + mode = this.ast.declare.MODE_BLOCK; } else { - body = this.read_statement(); + this.expect(';') && this.next(); + while(this.token != this.EOF && this.token !== this.tok.T_DECLARE) { + // @todo : check declare_statement from php / not valid + body.push(this.read_top_statement()); + } + mode = this.ast.declare.MODE_NONE; } - return result(options, body); - break; + return result(what, body, mode); case this.tok.T_TRY: return this.read_try(); @@ -304,14 +327,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 +351,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..97434c04c --- /dev/null +++ b/src/parser/utils.js @@ -0,0 +1,120 @@ +/*! + * 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,20 @@ 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 == '[') { + var offset = null; if (encapsed) { - result = this.next().read_encaps_var_offset(); + offset = this.next().read_encaps_var_offset(); } else { - var offset = this.next().token === ']' ? null : this.read_dim_offset(); - result = ['offset', result, offset]; + offset = this.next().token === ']' ? null : this.read_dim_offset(); } - this.expect(']').next(); + this.expect(']') && this.next(); + result = node('offsetlookup', result, offset); } 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 +258,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..565626488 --- /dev/null +++ b/test/arrayTests.js @@ -0,0 +1,202 @@ +var should = require("should"); +var parser = require('../src/index'); + +describe('Array without keys', function() { + + it('deference array', function () { + var ast = parser.parseEval([ + '$a = [', + '"a", "b"', + ']($foo)[$foo->bar()[1]]->foo()' + ].join('\r'), { + parser: { + debug: true + } + }); + console.log(ast); + }); + + 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 empty array', function() { + var ast = parser.parseEval('$a = []; $b = array();'); + ast.children[0].right.items.length.should.be.exactly(0); + ast.children[1].right.items.length.should.be.exactly(0); + }); + 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..dbea8f1f7 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,26 +9,25 @@ 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 syntax error', function() { + var err = null; + (function(){ + try { + var ast = parser.parseCode([ + '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..76eac675e --- /dev/null +++ b/test/exprTests.js @@ -0,0 +1,267 @@ +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 generators', function() { + var ast = parser.parseEval([ + 'function gen() {', + ' yield 0; // key 0', + ' yield from foo(); // keys 0-2', + ' yield 1 => $a; // key 1', + '}' + ].join('\n')); + var expr = ast.children[0].body.children; + expr[0].kind.should.be.exactly('yield'); + expr[0].value.kind.should.be.exactly('number'); + + expr[1].kind.should.be.exactly('yieldfrom'); + expr[1].value.kind.should.be.exactly('call'); + + expr[2].kind.should.be.exactly('yield'); + expr[2].key.kind.should.be.exactly('number'); + expr[2].value.kind.should.be.exactly('variable'); + }); + + 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);', + 'die();', + '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 namespace\\foo::class();', + '$a = new $foo();', + '$a = new class extends foo implements bar { };', + ].join('\n'), { + parser: { debug: false } + }); + ast.children[0].right.kind.should.be.exactly('new'); + ast.children[0].right.what.kind.should.be.exactly('identifier'); + + ast.children[2].right.kind.should.be.exactly('new'); + ast.children[2].right.what.kind.should.be.exactly('variable'); + + ast.children[3].right.kind.should.be.exactly('new'); + ast.children[3].right.what.kind.should.be.exactly('class'); + }); + + it('test nested expressions precedence', function() { + var ast = parser.parseEval([ + '$a = 5 * 2 + 1;', // same as (1 + (5 * 2)) + '$b = 5 * (2 + 1);', + '$c = 1 + 2 / 3 + 4;', // same as (1 + (4 + (2 / 3))) + ].join('\n'), { + parser: { debug: false } + }); + var aExpr = ast.children[0].right; + aExpr.kind.should.be.exactly('bin'); + aExpr.left.value.should.be.exactly('1'); + aExpr.type.should.be.exactly('+'); + + aExpr.right.left.value.should.be.exactly('5'); + aExpr.right.type.should.be.exactly('*'); + aExpr.right.right.value.should.be.exactly('2'); + + var bExpr = ast.children[1].right; + bExpr.kind.should.be.exactly('bin'); + bExpr.left.value.should.be.exactly('5'); + bExpr.type.should.be.exactly('*'); + + bExpr.right.kind.should.be.exactly('parenthesis'); + bExpr.right.inner.left.value.should.be.exactly('2'); + bExpr.right.inner.type.should.be.exactly('+'); + bExpr.right.inner.right.value.should.be.exactly('1'); + + var cExpr = ast.children[2].right; + cExpr.kind.should.be.exactly('bin'); + cExpr.left.value.should.be.exactly('1'); + cExpr.type.should.be.exactly('+'); + + cExpr.right.kind.should.be.exactly('bin'); + cExpr.right.left.value.should.be.exactly('4'); + cExpr.right.type.should.be.exactly('+'); + + cExpr.right.right.kind.should.be.exactly('bin'); + cExpr.right.right.left.value.should.be.exactly('2'); + cExpr.right.right.type.should.be.exactly('/'); + cExpr.right.right.right.value.should.be.exactly('3'); + + }); + +}); diff --git a/test/functionTests.js b/test/functionTests.js new file mode 100644 index 000000000..3555b1e43 --- /dev/null +++ b/test/functionTests.js @@ -0,0 +1,68 @@ +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;', + '};', + '$b = foo(...[1, null, 1, 2, 3]);' + ].join('\n')); + + + it('test variadic error', function () { + var astErr = parser.parseEval([ + '$b = foo(...[1, 2, 3], $a);' + ].join('\n'), { + parser: { + suppressErrors: true + } + }); + var msg = 'Unexpected argument after a variadic argument on line 1'; + astErr.errors.length.should.be.exactly(1); + astErr.errors[0].line.should.be.exactly(1); + astErr.errors[0].message.should.be.exactly(msg); + }); + + 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..29e76898f --- /dev/null +++ b/test/lexerTests.js @@ -0,0 +1,84 @@ +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..b3455dbd9 --- /dev/null +++ b/test/namespaceTest.js @@ -0,0 +1,98 @@ +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 + }); + + it('should work with declare statement', function() { + var ast = parser.parseEval([ + 'declare(strict_types=1);', + 'namespace foo;', + 'class bar {}' + ].join('\n'), { + parser: { + debug: false + } + }); + // @todo : make assertions + }); +}); 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 @@ -test;', + '$b = (new test())->foo();', + '$c = (foo())[5];', + '$d = (function($a) { return $a * 2; })(5);', + ].join('\n'), { + parser: { + debug: true + } + }); + + }); +}); diff --git a/test/statementTests.js b/test/statementTests.js new file mode 100644 index 000000000..a0218f06a --- /dev/null +++ b/test/statementTests.js @@ -0,0 +1,212 @@ +var should = require("should"); +var parser = require('../src/index'); + +describe('Test statements', function() { + it('test goto label', function() { + var ast = parser.parseEval([ + 'start:', + ' $i++;', + 'goto start;' + ].join('\n'), { + parser: { debug: false } + }); + ast.children[0].kind.should.be.exactly('label'); + ast.children[0].name.should.be.exactly('start'); + ast.children[1].kind.should.be.exactly('post'); + ast.children[2].kind.should.be.exactly('goto'); + ast.children[2].label.should.be.exactly('start'); + }); + + it('test global', function() { + var ast = parser.parseEval([ + 'function foo() {', + ' global $a, $b;', + '}' + ].join('\n'), { + parser: { debug: false } + }); + var expr = ast.children[0].body.children[0]; + expr.kind.should.be.exactly('global'); + expr.items[0].kind.should.be.exactly('variable'); + expr.items[0].name.should.be.exactly('a'); + expr.items[1].kind.should.be.exactly('variable'); + expr.items[1].name.should.be.exactly('b'); + }); + + it('test halt statement', function() { + var ast = parser.parseEval([ + '$a = 1;', + '__halt_compiler();', + '$b = 1;' + ].join('\n'), { + parser: { debug: false } + }); + ast.children.length.should.be.exactly(2); + ast.children[0].kind.should.be.exactly('assign'); + ast.children[1].kind.should.be.exactly('halt'); + ast.children[1].after.should.be.exactly('\n$b = 1;'); + + // test the inner error + (function() { + var ast = parser.parseEval([ + 'if (true) {', + ' __halt_compiler();', + '}' + ].join('\n')); + }).should.throw(/line\s2/); + + // test the fallback + ast = parser.parseEval([ + 'if (true) {', + ' __halt_compiler();', + '}', + '$b = 1;' + ].join('\n'), { + parser: { suppressErrors: true } + }); + + ast.children.length.should.be.exactly(2); + ast.errors.length.should.be.exactly(1); + ast.children[0].kind.should.be.exactly('if'); + ast.children[0].body.children[0].kind.should.be.exactly('halt'); + ast.children[0].body.children[0].after.should.be.exactly('\n}\n$b = 1;'); + ast.children[1].kind.should.be.exactly('assign'); + + }); + + it('test static', function() { + var ast = parser.parseEval([ + 'function foo() {', + ' static $a, $b = 5;', + '}', + 'static $sVar1 = 11;' + ].join('\n'), { + parser: { debug: false } + }); + + // test function multi statements + var expr = ast.children[0].body.children[0]; + expr.kind.should.be.exactly('static'); + expr.items.length.should.be.exactly(2); + expr.items[0].kind.should.be.exactly('variable'); + expr.items[1].kind.should.be.exactly('assign'); + + // test single statement + ast.children[1].kind.should.be.exactly('static'); + ast.children[1].items.length.should.be.exactly(1); + ast.children[1].items[0].kind.should.be.exactly('assign'); + ast.children[1].items[0].left.kind.should.be.exactly('variable'); + ast.children[1].items[0].left.name.should.be.exactly('sVar1'); + ast.children[1].items[0].right.kind.should.be.exactly('number'); + ast.children[1].items[0].right.value.should.be.exactly('11'); + + }); + + it('test declare', function() { + var ast = parser.parseEval([ + 'declare(ticks=1);', + '$a = 1;', + 'declare(ticks=2,encoding="ISO-8859-1");', + '$b = 1;', + 'declare(ticks=1) {', + ' $c = 2;', + '}', + 'declare(encoding="UTF-8"):', + ' $d = 3;', + 'enddeclare;', + '$e = 4;' // <- single statement + ].join('\n'), { + parser: { debug: false } + }); + ast.children.length.should.be.exactly(5); + + ast.children[0].kind.should.be.exactly('declare'); + ast.children[0].mode.should.be.exactly('none'); + ast.children[0].children.length.should.be.exactly(1); + ast.children[0].children[0].left.name.should.be.exactly('a'); + ast.children[0].what.ticks.kind.should.be.exactly('number'); + ast.children[0].what.ticks.value.should.be.exactly('1'); + + ast.children[1].kind.should.be.exactly('declare'); + ast.children[1].mode.should.be.exactly('none'); + ast.children[1].children.length.should.be.exactly(1); + ast.children[1].children[0].left.name.should.be.exactly('b'); + ast.children[1].what.ticks.kind.should.be.exactly('number'); + ast.children[1].what.ticks.value.should.be.exactly('2'); + ast.children[1].what.encoding.kind.should.be.exactly('string'); + ast.children[1].what.encoding.value.should.be.exactly('ISO-8859-1'); + + ast.children[2].kind.should.be.exactly('declare'); + ast.children[2].mode.should.be.exactly('block'); + ast.children[2].children.length.should.be.exactly(1); + ast.children[2].children[0].left.name.should.be.exactly('c'); + ast.children[2].what.ticks.kind.should.be.exactly('number'); + ast.children[2].what.ticks.value.should.be.exactly('1'); + + ast.children[3].kind.should.be.exactly('declare'); + ast.children[3].mode.should.be.exactly('short'); + ast.children[3].children.length.should.be.exactly(1); + ast.children[3].children[0].left.name.should.be.exactly('d'); + ast.children[3].what.encoding.kind.should.be.exactly('string'); + ast.children[3].what.encoding.value.should.be.exactly('UTF-8'); + + ast.children[4].kind.should.be.exactly('assign'); + }); + + it('test try', function() { + var ast = parser.parseEval([ + 'try {', + ' foo();', + '} catch(FooError|BarError $err) {', + ' var_dump($err);', + ' throw $err;', + '} finally {', + ' clean();', + '}' + ].join('\n'), { + parser: { debug: false } + }); + + var expr = ast.children[0]; + expr.kind.should.be.exactly('try'); + expr.body.kind.should.be.exactly('block'); + expr.body.children[0].kind.should.be.exactly('call'); + expr.body.children[0].what.name.should.be.exactly('foo'); + expr.catches.length.should.be.exactly(1); + + // test catch + var catchExpr = expr.catches[0]; + catchExpr.kind.should.be.exactly('catch'); + catchExpr.what.length.should.be.exactly(2); + catchExpr.what[0].name.should.be.exactly('FooError'); + catchExpr.what[1].name.should.be.exactly('BarError'); + catchExpr.variable.kind.should.be.exactly('variable'); + catchExpr.variable.name.should.be.exactly('err'); + + // test the throw statement + catchExpr.body.kind.should.be.exactly('block'); + catchExpr.body.children.length.should.be.exactly(2); + catchExpr.body.children[1].kind.should.be.exactly('throw'); + catchExpr.body.children[1].what.kind.should.be.exactly('variable'); + catchExpr.body.children[1].what.name.should.be.exactly('err'); + + // always block + expr.always.kind.should.be.exactly('block'); + }); + + it('test inner statements', function() { + var ast = parser.parseEval([ + 'if (true) {', + ' function foo() {}', + ' abstract class foo {}', + ' final class foo {}', + ' class foo {}', + ' trait foo {}', + ' interface foo {}', + '}' + ].join('\n'), { + parser: { debug: false } + }); + // @todo : do assert + }); +}); diff --git a/test/stringTests.js b/test/stringTests.js new file mode 100644 index 000000000..dfde29305 --- /dev/null +++ b/test/stringTests.js @@ -0,0 +1,222 @@ +var should = require("should"); +var parser = require('../src/index'); + +describe('Test strings', function() { + + it('...', function() { + var ast = parser.parseEval('$a = b\'\\t\\ra\';'); + }); + it('...', function() { + var ast = parser.parseEval('echo b"\\colors contains >$colors<\\n";'); + }); + it('...', function() { + var ast = parser.parseEval('echo B"\\colors[1] contains >$colors[1]<\\n";'); + }); + it('binary cast', function() { + var ast = parser.parseEval('echo (binary)"\\colors[1] contains >$colors[1]<\\n";'); + console.log(ast.children[0].arguments[0]); + }); + it('...', function() { + var ast = parser.parseEval('echo "\\colors[1] contains >$colors [1]<\\n";'); + }); + it('...', function() { + var ast = parser.parseEval('echo "~\'.{{$expectedLength}}\'\\$~s";'); + }); + it('test encapsed variable', function() { + var ast = parser.parseEval([ + 'echo "Hello $obj->name !";', + 'echo "Hello $obj->foo->bar !";', + 'echo "Hello $obj[1]->foo !";' + ].join('\n')); + + ast.children[0].arguments[0].kind.should.be.exactly('encapsed'); + ast.children[0].arguments[0].value[0].value.should.be.exactly('Hello '); + ast.children[0].arguments[0].value[2].value.should.be.exactly(' !'); + + ast.children[1].arguments[0].kind.should.be.exactly('encapsed'); + ast.children[1].arguments[0].value[0].value.should.be.exactly('Hello '); + ast.children[1].arguments[0].value[2].value.should.be.exactly('->bar !'); + + ast.children[2].arguments[0].kind.should.be.exactly('encapsed'); + ast.children[2].arguments[0].value[0].value.should.be.exactly('Hello '); + ast.children[2].arguments[0].value[2].value.should.be.exactly('->foo !'); + }); + 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('test encapsed elements', function() { + var ast = parser.parseEval([ + '$code = <<<\t EOFX', + '{$this->docStar}', + '${$foo}', + '${targetDirs[1]}', + '$test[1]', + '$test->foo', + 'EOFX;' + ].join('\r'), { + parser: { + debug: false + } + }); + var expr = ast.children[0].right.value; + expr[0].kind.should.be.exactly('propertylookup'); + expr[2].kind.should.be.exactly('variable'); + expr[4].kind.should.be.exactly('variable'); + expr[6].kind.should.be.exactly('offsetlookup'); + expr[8].kind.should.be.exactly('propertylookup'); + // @todo : improve assertions + }); + it('test nowdoc label and contents', function() { + var ast = parser.parseEval([ + '$code .= <<<\'EOF\'', + ' }', + 'EOF;' + ].join('\r\n'), { + parser: { + debug: false + } + }); + var expr = ast.children[0].right; + expr.kind.should.be.exactly('nowdoc'); + expr.label.should.be.exactly('EOF'); + expr.value.should.be.exactly(' }'); + }); + 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 << 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('?'); + }); + }); +});