php-parser
Advanced tools
Comparing version 2.1.0 to 2.2.0
{ | ||
"name": "php-parser", | ||
"version": "2.1.0", | ||
"version": "2.2.0", | ||
"description": "Parse PHP code and returns its AST", | ||
@@ -5,0 +5,0 @@ "main": "src/index.js", |
@@ -33,3 +33,4 @@ <h1 align="center">php-parser</h1> | ||
parser: { | ||
extractDoc: true | ||
extractDoc: true, | ||
php7: true | ||
}, | ||
@@ -78,5 +79,6 @@ ast: { | ||
Try it online (demo) : | ||
http://glayzzle.com/php-parser/#demo | ||
- Try it online (demo) : http://glayzzle.com/php-parser/#demo | ||
- Or from AST Explorer : https://astexplorer.net/ | ||
API Overview | ||
@@ -83,0 +85,0 @@ ------------ |
# Releases | ||
## 2.2.0 : (2017-12-27) | ||
- Impl #108 : add an option to disable PHP7 support | ||
- Fix #107 : fix T_DOUBLE_COLON handler | ||
- Fix #106 : infinite loops from lexer (unput) | ||
- Fix #105 : T_DOLLAR_OPEN_CURLY_BRACES handles now expressions | ||
- PR #102 : Normalize the way type casts are defined | ||
- Fix #103 : Fix critical cast to null confusion | ||
## 2.1.0 : (2017-11-01) | ||
@@ -4,0 +12,0 @@ - Impl #91 & #92 : Functions support reserved names (PHP7) |
@@ -45,3 +45,4 @@ /*! | ||
* extractDoc: true, | ||
* suppressErrors: true | ||
* suppressErrors: true, | ||
* php7: true | ||
* }, | ||
@@ -79,2 +80,9 @@ * ast: { | ||
if (options && typeof options === 'object') { | ||
// disable php7 from lexer if already disabled from parser | ||
if (options.parser && options.parser.php7 === false) { | ||
if (!options.lexer) { | ||
options.lexer = {}; | ||
} | ||
options.lexer.php7 = false; | ||
} | ||
combine(options, this); | ||
@@ -81,0 +89,0 @@ } |
@@ -31,2 +31,3 @@ /*! | ||
this.short_tags = true; | ||
this.php7 = true; | ||
this.yyprevcol = 0; | ||
@@ -33,0 +34,0 @@ this.keywords = { |
@@ -28,7 +28,7 @@ /*! | ||
if (ch === 'x' || ch === 'X') { | ||
this.input(); | ||
ch = this.input(); | ||
if (this.is_HEX()) { | ||
return this.consume_HNUM(); | ||
} else { | ||
this.unput(2); | ||
this.unput(ch ? 2 : 1); | ||
} | ||
@@ -40,6 +40,6 @@ } else if (ch === 'b' || ch === 'B') { | ||
} else { | ||
this.unput(2); | ||
this.unput(ch ? 2 : 1); | ||
} | ||
} else if (!this.is_NUM()) { | ||
this.unput(1); | ||
if (ch) this.unput(1); | ||
} | ||
@@ -61,3 +61,3 @@ } | ||
} else { | ||
if (ch) this.unput(3); | ||
this.unput(ch ? 3 : 2); | ||
break; | ||
@@ -69,7 +69,7 @@ } | ||
} else { | ||
if (ch) this.unput(2); | ||
this.unput(ch ? 2 : 1); | ||
break; | ||
} | ||
} else { | ||
this.unput(1); | ||
if (ch) this.unput(1); | ||
break; | ||
@@ -98,5 +98,5 @@ } | ||
while(this.offset < this.size) { | ||
this.input(); | ||
var ch = this.input(); | ||
if (!this.is_HEX()) { | ||
this.unput(1); | ||
if (ch) this.unput(1); | ||
break; | ||
@@ -110,5 +110,5 @@ } | ||
while(this.offset < this.size) { | ||
this.input(); | ||
var ch = this.input(); | ||
if (!this.is_NUM()) { | ||
this.unput(1); | ||
if (ch) this.unput(1); | ||
break; | ||
@@ -115,0 +115,0 @@ } |
@@ -29,21 +29,23 @@ /*! | ||
var ch = this.input(); | ||
// SHIFT STATE | ||
this.popState(); | ||
this.begin('ST_IN_SCRIPTING'); | ||
if (this.is_LABEL_START()) { | ||
this.consume_LABEL(); | ||
ch = this.input(); | ||
this.popState(); | ||
if (ch === '[' || ch === '}') { | ||
this.begin('ST_IN_SCRIPTING'); | ||
this.unput(1); | ||
return this.tok.T_STRING_VARNAME; | ||
} else { | ||
// any char (that's started with a label sequence) | ||
this.unput(this.yytext.length); | ||
return false; | ||
} | ||
} else { | ||
// any char (thats not a label start sequence) | ||
if (ch) this.unput(1); | ||
this.popState(); | ||
this.begin('ST_IN_SCRIPTING'); | ||
// console.log(this.yylineno, 'ST_LOOKING_FOR_VARNAME', this._input[this.offset - 1], this.conditionStack); | ||
return false; | ||
} | ||
// stops looking for a varname and starts the scripting mode | ||
return false; | ||
}, | ||
@@ -50,0 +52,0 @@ matchST_VAR_OFFSET: function() { |
@@ -95,3 +95,3 @@ /*! | ||
} | ||
this.unput(1); | ||
if (ch) this.unput(1); | ||
break; | ||
@@ -98,0 +98,0 @@ } |
@@ -93,3 +93,3 @@ /*! | ||
} | ||
this.unput(1); | ||
if (ch) this.unput(1); | ||
} else if (ch == '{') { | ||
@@ -101,3 +101,3 @@ ch = this.input(); | ||
} | ||
this.unput(1); | ||
if (ch) this.unput(1); | ||
} | ||
@@ -257,6 +257,6 @@ } | ||
} | ||
} else { | ||
this.unput(1); | ||
} | ||
return this.tok.T_VARIABLE; | ||
} else { | ||
if (ch) this.unput(1); | ||
} | ||
return this.tok.T_VARIABLE; | ||
}, | ||
@@ -318,3 +318,3 @@ // HANDLES BACKQUOTES | ||
} | ||
this.unput(1); | ||
continue; | ||
} else if (ch === '{') { | ||
@@ -334,3 +334,3 @@ ch = this.input(); | ||
} | ||
this.unput(1); | ||
continue; | ||
} | ||
@@ -397,3 +397,3 @@ ch = this.input(); | ||
} | ||
this.unput(1); | ||
if (ch) this.unput(1); | ||
} else if (ch === '{') { | ||
@@ -400,0 +400,0 @@ ch = this.input(); |
@@ -12,3 +12,3 @@ /*! | ||
if (token === 'yield') { | ||
if (this.tryMatch(' from')) { | ||
if (this.php7 && this.tryMatch(' from')) { | ||
this.consume(5); | ||
@@ -155,3 +155,3 @@ id = this.tok.T_YIELD_FROM; | ||
'?': function() { | ||
if (this._input[this.offset] === '?') { | ||
if (this.php7 && this._input[this.offset] === '?') { | ||
this.input(); | ||
@@ -178,3 +178,3 @@ return this.tok.T_COALESCE; | ||
this.input(); | ||
if (this._input[this.offset] === '>') { | ||
if (this.php7 && this._input[this.offset] === '>') { | ||
this.input(); | ||
@@ -181,0 +181,0 @@ return this.tok.T_SPACESHIP; |
@@ -41,5 +41,5 @@ /*! | ||
while(this.offset < this.size) { | ||
this.input(); | ||
var ch = this.input(); | ||
if (!this.is_LABEL()) { | ||
this.unput(1); | ||
if (ch) this.unput(1); | ||
break; | ||
@@ -69,5 +69,5 @@ } | ||
while(this.offset < this.size) { | ||
this.input(); | ||
var ch = this.input(); | ||
if (!this.is_TABSPACE()) { | ||
this.unput(1); | ||
if (ch) this.unput(1); | ||
break; | ||
@@ -74,0 +74,0 @@ } |
@@ -33,16 +33,11 @@ /*! | ||
this.debug = false; | ||
this.php7 = true; | ||
this.extractDoc = false; | ||
this.suppressErrors = false; | ||
var mapIt = function(item) { | ||
return [item, null]; | ||
}; | ||
this.entries = { | ||
'IDENTIFIER': [ | ||
this.tok.T_CLASS_C, | ||
this.tok.T_DIR, | ||
this.tok.T_FILE, | ||
this.tok.T_FUNC_C, | ||
this.tok.T_LINE, | ||
this.tok.T_METHOD_C, | ||
this.tok.T_NS_C, | ||
this.tok.T_TRAIT, | ||
'IDENTIFIER': new Map([ | ||
this.tok.T_ABSTRACT, | ||
this.tok.T_LOGICAL_AND, | ||
this.tok.T_ARRAY, | ||
@@ -55,2 +50,3 @@ this.tok.T_AS, | ||
this.tok.T_CLASS, | ||
this.tok.T_CLASS_C, | ||
this.tok.T_CLONE, | ||
@@ -61,2 +57,3 @@ this.tok.T_CONST, | ||
this.tok.T_DEFAULT, | ||
this.tok.T_DIR, | ||
this.tok.T_DO, | ||
@@ -76,4 +73,6 @@ this.tok.T_ECHO, | ||
this.tok.T_EXTENDS, | ||
this.tok.T_FILE, | ||
this.tok.T_FINAL, | ||
this.tok.T_FINALLY, | ||
this.tok.T_FUNC_C, | ||
this.tok.T_FOR, | ||
@@ -92,6 +91,11 @@ this.tok.T_FOREACH, | ||
this.tok.T_ISSET, | ||
this.tok.T_LINE, | ||
this.tok.T_LIST, | ||
this.tok.T_LOGICAL_AND, | ||
this.tok.T_LOGICAL_OR, | ||
this.tok.T_LOGICAL_XOR, | ||
this.tok.T_METHOD_C, | ||
this.tok.T_NAMESPACE, | ||
this.tok.T_NEW, | ||
this.tok.T_LOGICAL_OR, | ||
this.tok.T_NS_C, | ||
this.tok.T_PRINT, | ||
@@ -113,6 +117,5 @@ this.tok.T_PRIVATE, | ||
this.tok.T_WHILE, | ||
this.tok.T_LOGICAL_XOR, | ||
this.tok.T_YIELD | ||
], | ||
'VARIABLE': [ | ||
].map(mapIt)), | ||
'VARIABLE': new Map([ | ||
this.tok.T_VARIABLE, | ||
@@ -124,4 +127,4 @@ '$', '&', | ||
this.tok.T_STATIC | ||
], | ||
'SCALAR': [ | ||
].map(mapIt)), | ||
'SCALAR': new Map([ | ||
this.tok.T_CONSTANT_ENCAPSED_STRING, | ||
@@ -145,4 +148,4 @@ this.tok.T_START_HEREDOC, | ||
this.tok.T_NS_SEPARATOR | ||
], | ||
'T_MAGIC_CONST': [ | ||
].map(mapIt)), | ||
'T_MAGIC_CONST': new Map([ | ||
this.tok.T_CLASS_C, | ||
@@ -156,4 +159,4 @@ this.tok.T_TRAIT_C, | ||
this.tok.T_NS_C | ||
], | ||
'T_MEMBER_FLAGS': [ | ||
].map(mapIt)), | ||
'T_MEMBER_FLAGS': new Map([ | ||
this.tok.T_PUBLIC, | ||
@@ -165,4 +168,4 @@ this.tok.T_PRIVATE, | ||
this.tok.T_FINAL | ||
], | ||
'EOS': [ | ||
].map(mapIt)), | ||
'EOS': new Map([ | ||
';', | ||
@@ -172,4 +175,4 @@ this.tok.T_CLOSE_TAG, | ||
this.tok.T_INLINE_HTML | ||
], | ||
'EXPR': [ | ||
].map(mapIt)), | ||
'EXPR': new Map([ | ||
'@','-','+','!','~','(','`', | ||
@@ -220,3 +223,3 @@ this.tok.T_LIST, | ||
this.tok.T_NS_C | ||
] | ||
].map(mapIt)) | ||
}; | ||
@@ -450,5 +453,4 @@ }; | ||
return type.indexOf(this.token) !== -1; | ||
} else { | ||
return this.entries[type].indexOf(this.token) != -1; | ||
} | ||
return this.entries[type].has(this.token); | ||
}; | ||
@@ -455,0 +457,0 @@ |
@@ -180,3 +180,3 @@ /*! | ||
* ```ebnf | ||
* constant_declaration ::= T_STRING '=' expr | ||
* constant_declaration ::= (T_STRING | IDENTIFIER) '=' expr | ||
* ``` | ||
@@ -186,6 +186,10 @@ * @return {Constant} [:link:](AST.md#constant) | ||
function read_constant_declaration() { | ||
var result = this.node('classconstant'), name = null, value = null; | ||
if (this.is('IDENTIFIER') || this.expect(this.tok.T_STRING)) { | ||
var result = this.node('classconstant'), | ||
name = null, | ||
value = null; | ||
if (this.token === this.tok.T_STRING || (this.php7 && this.is('IDENTIFIER'))) { | ||
name = this.text(); | ||
this.next(); | ||
} else { | ||
this.expect('IDENTIFIER'); | ||
} | ||
@@ -396,2 +400,4 @@ if (this.expect('=')) { | ||
* ``` | ||
* name list : https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L303 | ||
* trait adaptation : https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L742 | ||
*/ | ||
@@ -412,6 +418,8 @@ ,read_trait_use_alias: function() { | ||
if (this.is('IDENTIFIER') || this.expect(this.tok.T_STRING)) { | ||
if (this.token === this.tok.T_STRING || (this.php7 && this.is('IDENTIFIER'))) { | ||
trait = method; | ||
method = this.text(); | ||
this.next(); | ||
} else { | ||
this.expect(this.tok.T_STRING); | ||
} | ||
@@ -441,3 +449,3 @@ } else { | ||
if (this.is('IDENTIFIER') || this.token === this.tok.T_STRING) { | ||
if (this.token === this.tok.T_STRING || (this.php7 && this.is('IDENTIFIER'))) { | ||
alias = this.text(); | ||
@@ -444,0 +452,0 @@ this.next(); |
@@ -275,3 +275,3 @@ /*! | ||
case this.tok.T_DOUBLE_CAST: | ||
return this.node('cast')('double', this.next().read_expr()); | ||
return this.node('cast')('float', this.next().read_expr()); | ||
@@ -288,8 +288,6 @@ case this.tok.T_STRING_CAST: | ||
case this.tok.T_BOOL_CAST: | ||
return this.node('cast')('boolean', this.next().read_expr()); | ||
return this.node('cast')('bool', this.next().read_expr()); | ||
case this.tok.T_UNSET_CAST: | ||
return this.node('unset')( | ||
this.next().read_expr() | ||
); | ||
return this.node('cast')('unset', this.next().read_expr()); | ||
@@ -296,0 +294,0 @@ case this.tok.T_EXIT: |
@@ -13,3 +13,3 @@ /*! | ||
if (this.token == '&') { | ||
this.next(); | ||
this.next().ignoreComments(); | ||
return true; | ||
@@ -24,3 +24,3 @@ } | ||
if (this.token === this.tok.T_ELLIPSIS) { | ||
this.next(); | ||
this.next().ignoreComments(); | ||
return true; | ||
@@ -76,3 +76,3 @@ } | ||
if (this.expect(this.tok.T_FUNCTION)) { | ||
this.next(); | ||
this.next().ignoreComments(); | ||
} | ||
@@ -82,7 +82,14 @@ var isRef = this.is_reference(); | ||
if (type !== 1) { | ||
if ((type === 2 && this.is('IDENTIFIER')) || this.expect(this.tok.T_STRING)) { | ||
name = this.text(); | ||
this.next(); | ||
if (type === 2) { | ||
if (this.token === this.tok.T_STRING || (this.php7 && this.is('IDENTIFIER'))) { | ||
name = this.text(); | ||
this.next(); | ||
} else { | ||
this.error('IDENTIFIER'); | ||
} | ||
} else { | ||
this.next(); | ||
if (this.expect(this.tok.T_STRING)) { | ||
name = this.text(); | ||
} | ||
this.next(); | ||
} | ||
@@ -89,0 +96,0 @@ } |
@@ -79,4 +79,5 @@ /*! | ||
} else if ( | ||
this.is('IDENTIFIER') || this.token === this.tok.T_STRING | ||
|| this.token === this.tok.T_CLASS | ||
this.token === this.tok.T_STRING | ||
|| this.token === this.tok.T_CLASS | ||
|| (this.php7 && this.is('IDENTIFIER')) | ||
) { | ||
@@ -131,18 +132,23 @@ offset = this.node('constref'); | ||
case this.tok.T_DOUBLE_COLON: | ||
var node = this.node('staticlookup'), offset; | ||
this.next(); | ||
if(this.is('IDENTIFIER') || this.token === this.tok.T_STRING | ||
|| this.token === this.tok.T_CLASS | ||
) { | ||
offset = this.node('constref'); | ||
// @see https://github.com/glayzzle/php-parser/issues/107#issuecomment-354104574 | ||
if(result.kind === 'staticlookup') { | ||
this.error(); | ||
} | ||
var node = this.node('staticlookup'); | ||
if(this.next().token === this.tok.T_STRING || (this.php7 && this.is('IDENTIFIER'))) { | ||
var offset = this.node('constref'); | ||
var name = this.text(); | ||
this.next(); | ||
offset = offset(name); | ||
if(this.token === this.tok.T_OBJECT_OPERATOR || this.token === this.tok.T_DOUBLE_COLON) { | ||
if(this.token === this.tok.T_OBJECT_OPERATOR) { | ||
this.error(); | ||
} | ||
} else { | ||
this.error(this.tok.T_STRING); | ||
// fallback on a constref node | ||
var offset = this.node('constref')(this.text()); | ||
this.next(); | ||
} | ||
result = node(result, offset); | ||
@@ -149,0 +155,0 @@ break; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2499079
23558
120