Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

php-parser

Package Overview
Dependencies
Maintainers
2
Versions
77
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

php-parser - npm Package Compare versions

Comparing version 3.0.3 to 3.1.0-beta.0

src/ast/.nowdoc.js.swp

26

package.json
{
"name": "php-parser",
"version": "3.0.3",
"version": "3.1.0-beta.0",
"description": "Parse PHP code from JS and returns its AST",

@@ -63,20 +63,20 @@ "main": "src/index.js",

"devDependencies": {
"@babel/core": "^7.3.4",
"@babel/preset-env": "^7.3.4",
"@babel/core": "^7.16.12",
"@babel/preset-env": "^7.16.11",
"babel-loader": "^8.0.5",
"coveralls": "^3.0.3",
"eslint": "^5.15.0",
"eslint-plugin-jest": "^24.0.0",
"eslint-plugin-prettier": "^3.0.1",
"husky": "^6.0.0",
"jest": "^26.4.2",
"jest-runner-eslint": "^0.9.0",
"jsdoc": "^3.5.5",
"eslint": "^7.32.0",
"eslint-plugin-jest": "^26.0.0",
"eslint-plugin-prettier": "^4.0.0",
"husky": "^7.0.4",
"jest": "^27.4.7",
"jest-runner-eslint": "^1.0.0",
"jsdoc": "^3.6.10",
"jsdoc-template": "^1.2.0",
"lodash.template": ">=4.5.0",
"prettier": "^2.0.2",
"prettier": "^2.5.1",
"tsd-jsdoc": "^2.5.0",
"webpack": "^5.30.0",
"webpack-cli": "^4.6.0"
"webpack": "^5.68.0",
"webpack-cli": "^4.9.2"
}
}
<h1 align="center">php-parser</h1>
<p align="center">
<a href="https://travis-ci.org/glayzzle/php-parser"><img src="https://api.travis-ci.org/glayzzle/php-parser.svg?branch=2.2.0"></a>
<a href="https://circleci.com/gh/glayzzle/php-parser/tree/master"><img src="https://circleci.com/gh/glayzzle/php-parser/tree/master.svg?style=svg"></a>
<a href="https://coveralls.io/github/glayzzle/php-parser?branch=master"><img src="https://coveralls.io/repos/github/glayzzle/php-parser/badge.svg?branch=master&v=20170115" alt="Coverage Status" /></a>

@@ -5,0 +5,0 @@ <a title="npm version" href="https://www.npmjs.com/package/php-parser"><img src="https://badge.fury.io/js/php-parser.svg"></a>

@@ -132,19 +132,2 @@ /**

/**
* Create a position node from specified parser
* including it's lexer current state
* @private
* @function AST#position
* @memberOf module:php-parser
* @param {Parser} 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
);
};
// operators in ascending order of precedence

@@ -222,2 +205,3 @@ AST.precedence = {};

}
/* istanbul ignore next */
if (target.loc.end.offset < last.loc.end.offset) {

@@ -312,3 +296,3 @@ target.loc.end = last.loc.end;

if (result.what && !result.what.parenthesizedExpression) {
// unary precedence is allways lower
// unary precedence is always lower
if (result.what.kind === "bin") {

@@ -381,3 +365,3 @@ buffer = result.what;

if (this.withPositions || this.withSource) {
start = this.position(parser);
start = parser.position();
}

@@ -401,3 +385,3 @@ const self = this;

);
// last argument is allways the location
// last argument is always the location
args.push(location);

@@ -417,2 +401,3 @@ }

result.instance = astNode;
/* istanbul ignore next */
if (result.trailingComments) {

@@ -484,3 +469,3 @@ // buffer of trailingComments

for (const k in AST.stack) {
if (AST.stack.hasOwnProperty(k)) {
if (Object.prototype.hasOwnProperty.call(AST.stack, k)) {
errors.push(AST.stack[k]);

@@ -499,2 +484,4 @@ }

require("./ast/assignref"),
require("./ast/attribute"),
require("./ast/attrgroup"),
require("./ast/bin"),

@@ -550,5 +537,8 @@ require("./ast/block"),

require("./ast/magic"),
require("./ast/match"),
require("./ast/matcharm"),
require("./ast/method"),
require("./ast/name"),
require("./ast/namespace"),
require("./ast/namedargument"),
require("./ast/new"),

@@ -559,2 +549,3 @@ require("./ast/node"),

require("./ast/nullkeyword"),
require("./ast/nullsafepropertylookup"),
require("./ast/number"),

@@ -592,2 +583,3 @@ require("./ast/offsetlookup"),

require("./ast/unary"),
require("./ast/uniontype"),
require("./ast/unset"),

@@ -594,0 +586,0 @@ require("./ast/usegroup"),

@@ -17,3 +17,3 @@ /**

* @property {Identifier[]} what
* @property {Variable} variable
* @property {Variable|null} variable
* @property {Statement} body

@@ -20,0 +20,0 @@ * @see http://php.net/manual/en/language.exceptions.php

@@ -19,2 +19,3 @@ /**

* @property {Declaration[]} body
* @property {AttrGroup[]} attrGroups
* @property {boolean} isAnonymous

@@ -32,4 +33,5 @@ * @property {boolean} isAbstract

this.body = body;
this.attrGroups = [];
this.parseFlags(flags);
}
);

@@ -22,8 +22,10 @@ /**

* @property {string} visibility
* @property {AttrGroup[]} attrGroups
*/
const ClassConstant = ConstantStatement.extends(
KIND,
function ClassConstant(kind, constants, flags, docs, location) {
function ClassConstant(kind, constants, flags, attrGroups, docs, location) {
ConstantStatement.apply(this, [kind || KIND, constants, docs, location]);
this.parseFlags(flags);
this.attrGroups = attrGroups;
}

@@ -44,2 +46,3 @@ );

} else if (flags[0] === null) {
/* istanbul ignore next */
this.visibility = null;

@@ -46,0 +49,0 @@ } else if (flags[0] === 0) {

@@ -23,2 +23,3 @@ /**

* @property {boolean} isStatic
* @property {AttrGroup[]} attrGroups
*/

@@ -45,3 +46,4 @@ module.exports = Expression.extends(

this.body = null;
this.attrGroups = [];
}
);

@@ -46,2 +46,3 @@ /**

} else if (flags[0] === null) {
/* istanbul ignore next */
this.visibility = null;

@@ -48,0 +49,0 @@ } else if (flags[0] === 0) {

@@ -21,2 +21,3 @@ /**

* @property {Block|null} body
* @property {AttrGroups[]} attrGroups
*/

@@ -32,3 +33,4 @@ module.exports = Declaration.extends(

this.body = null;
this.attrGroups = [];
}
);

@@ -18,10 +18,12 @@ /**

* @property {Declaration[]} body
* @property {AttrGroup[]} attrGroups
*/
module.exports = Declaration.extends(
KIND,
function Interface(name, ext, body, docs, location) {
function Interface(name, ext, body, attrGroups, docs, location) {
Declaration.apply(this, [KIND, name, docs, location]);
this.extends = ext;
this.body = body;
this.attrGroups = attrGroups;
}
);

@@ -44,2 +44,3 @@ /**

if (!node) {
/* istanbul ignore next */
throw new Error(

@@ -46,0 +47,0 @@ "Node already initialized, you must swap with another node"

@@ -11,2 +11,9 @@ /**

// eslint-disable-next-line no-unused-vars
const MODIFIER_PUBLIC = 1;
// eslint-disable-next-line no-unused-vars
const MODIFIER_PROTECTED = 2;
// eslint-disable-next-line no-unused-vars
const MODIFIER_PRIVATE = 4;
/**

@@ -22,2 +29,4 @@ * Defines a function parameter

* @property {boolean} nullable
* @property {AttrGroups[]} attrGroups
* @property {MODIFIER_PUBLIC|MODIFIER_PROTECTED|MODIFIER_PRIVATE} flags
*/

@@ -33,2 +42,3 @@ module.exports = Declaration.extends(

nullable,
flags,
docs,

@@ -43,3 +53,5 @@ location

this.nullable = nullable;
this.flags = flags || 0;
this.attrGroups = [];
}
);

@@ -20,6 +20,7 @@ /**

* @property {Identifier|Array<Identifier>|null} type
* @property {AttrGroup[]} attrGroups
*/
module.exports = Statement.extends(
KIND,
function Property(name, value, nullable, type, docs, location) {
function Property(name, value, nullable, type, attrGroups, docs, location) {
Statement.apply(this, [KIND, docs, location]);

@@ -30,3 +31,4 @@ this.name = name;

this.type = type;
this.attrGroups = attrGroups;
}
);

@@ -18,3 +18,3 @@ /**

* @property {Catch[]} catches
* @property {Block} allways
* @property {Block} always
*/

@@ -21,0 +21,0 @@ module.exports = Statement.extends(

@@ -37,4 +37,5 @@ /**

"void",
"static",
];
module.exports = TypeReference;

@@ -96,4 +96,4 @@ /**

}
if (options.parser.version < 500 || options.parser.version > 704) {
throw new Error("Can only handle versions between 5.x to 7.x");
if (options.parser.version < 500 || options.parser.version > 900) {
throw new Error("Can only handle versions between 5.x to 8.x");
}

@@ -203,4 +203,4 @@ }

* > 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]
* @param {string} buffer
* @return {Array<string|string[]>} - Each item can be a string or an array with following informations [token_name, text, line_number]
*/

@@ -218,3 +218,3 @@ Engine.prototype.tokenGetAll = function (buffer) {

let entry = this.lexer.yytext;
if (names.hasOwnProperty(token)) {
if (Object.prototype.hasOwnProperty.call(names, token)) {
entry = [names[token], entry, this.lexer.yylloc.first_line];

@@ -221,0 +221,0 @@ }

@@ -33,3 +33,3 @@ /**

this.short_tags = false;
this.version = 704;
this.version = 800;
this.yyprevcol = 0;

@@ -111,2 +111,3 @@ this.keywords = {

xor: this.tok.T_LOGICAL_XOR,
match: this.tok.T_MATCH,
};

@@ -181,2 +182,3 @@ this.castKeywords = {

// for backward compatible
/* istanbul ignore next */
toString: function () {

@@ -455,2 +457,3 @@ this.label;

this.stateCb = this["match" + condition];
/* istanbul ignore next */
if (typeof this.stateCb !== "function") {

@@ -473,2 +476,3 @@ throw new Error('Undefined condition state "' + condition + '"');

this.stateCb = this["match" + this.curCondition];
/* istanbul ignore next */
if (typeof this.stateCb !== "function") {

@@ -515,2 +519,3 @@ throw new Error('Undefined condition state "' + this.curCondition + '"');

}
/* istanbul ignore next */
if (this.debug) {

@@ -545,2 +550,3 @@ let tName = token;

[
require("./lexer/attribute.js"),
require("./lexer/comments.js"),

@@ -547,0 +553,0 @@ require("./lexer/initial.js"),

@@ -69,2 +69,3 @@ /**

} else {
/* istanbul ignore next */
throw new Error("Unexpected terminal");

@@ -92,2 +93,3 @@ }

} else {
/* istanbul ignore next */
throw new Error("Unexpected terminal");

@@ -94,0 +96,0 @@ }

@@ -19,2 +19,7 @@ /**

case "#":
if (this.version >= 800 && this._input[this.offset] === "[") {
this.input();
this.begin("ST_ATTRIBUTE");
return this.tok.T_ATTRIBUTE;
}
return this.T_COMMENT();

@@ -21,0 +26,0 @@ case "/":

@@ -165,2 +165,10 @@ /**

}
if (
this.version >= 800 &&
this._input[this.offset] === "-" &&
this._input[this.offset + 1] === ">"
) {
this.consume(2);
return this.tok.T_NULLSAFE_OBJECT_OPERATOR;
}
return "?";

@@ -167,0 +175,0 @@ },

@@ -8,2 +8,4 @@ /**

const Position = require("./ast/position");
/**

@@ -38,3 +40,3 @@ * @private

this.debug = false;
this.version = 704;
this.version = 800;
this.extractDoc = false;

@@ -102,2 +104,3 @@ this.extractTokens = false;

this.tok.T_LOGICAL_XOR,
this.tok.T_MATCH,
this.tok.T_METHOD_C,

@@ -199,2 +202,3 @@ this.tok.T_NAMESPACE,

this.tok.T_EMPTY,
this.tok.T_MATCH,
this.tok.T_INCLUDE,

@@ -313,2 +317,3 @@ this.tok.T_INCLUDE_ONCE,

const errors = this.ast.checkNodes();
/* istanbul ignore next */
if (errors.length > 0) {

@@ -376,2 +381,3 @@ errors.forEach(function (error) {

let symbol = this.text();
/* istanbul ignore next */
if (symbol.length > 10) {

@@ -394,2 +400,15 @@ symbol = symbol.substring(0, 7) + "...";

/**
* Create a position node from the lexers position
*
* @return {Position}
*/
Parser.prototype.position = function () {
return new Position(
this.lexer.yylloc.first_line,
this.lexer.yylloc.first_column,
this.lexer.yylloc.first_offset
);
};
/**
* Creates a new AST node

@@ -405,2 +424,3 @@ * @function Parser#node

this._docIndex = this._docs.length;
/* istanbul ignore next */
if (this.debug) {

@@ -508,2 +528,3 @@ // eslint-disable-next-line no-console

for (let i = 0; i < ignoreStack.length; i++) {
/* istanbul ignore next */
if (line.substring(3, 3 + ignoreStack[i].length) === ignoreStack[i]) {

@@ -514,2 +535,3 @@ found = true;

}
/* istanbul ignore next */
if (!found) {

@@ -625,6 +647,11 @@ break;

// the token
this.token = this.lexer.lex() || this.EOF;
this.token = this.lexer.lex() || /* istanbul ignore next */ this.EOF;
if (this.token === this.EOF) return this;
let entry = this.lexer.yytext;
if (this.lexer.engine.tokens.values.hasOwnProperty(this.token)) {
if (
Object.prototype.hasOwnProperty.call(
this.lexer.engine.tokens.values,
this.token
)
) {
entry = [

@@ -664,3 +691,3 @@ this.lexer.engine.tokens.values[this.token],

} else {
this.token = this.lexer.lex() || this.EOF;
this.token = this.lexer.lex() || /* istanbul ignore next */ this.EOF;
}

@@ -701,3 +728,4 @@ return this;

for (const k in ext) {
if (Parser.prototype.hasOwnProperty(k)) {
/* istanbul ignore next */
if (Object.prototype.hasOwnProperty.call(Parser.prototype, k)) {
// @see https://github.com/glayzzle/php-parser/issues/234

@@ -704,0 +732,0 @@ throw new Error("Function " + k + " is already defined - collision");

@@ -15,3 +15,3 @@ /**

*/
read_class_declaration_statement: function () {
read_class_declaration_statement: function (attrs) {
const result = this.node("class");

@@ -34,3 +34,5 @@ const flag = this.read_class_modifiers();

const body = this.next().read_class_body();
return result(propName, propExtends, propImplements, body, flag);
const node = result(propName, propExtends, propImplements, body, flag);
if (attrs) node.attrGroups = attrs;
return node;
},

@@ -64,3 +66,3 @@

let result = [];
let attrs = [];
while (this.token !== this.EOF && this.token !== "}") {

@@ -83,2 +85,8 @@ if (this.token === this.tok.T_COMMENT) {

if (this.token === this.tok.T_ATTRIBUTE) {
attrs = this.read_attr_list();
}
const locStart = this.position();
// read member flags

@@ -89,3 +97,3 @@ const flags = this.read_member_flags(false);

if (this.token === this.tok.T_CONST) {
const constants = this.read_constant_list(flags);
const constants = this.read_constant_list(flags, attrs);
if (this.expect(";")) {

@@ -107,3 +115,4 @@ this.next();

// reads a function
result.push(this.read_function(false, flags));
result.push(this.read_function(false, flags, attrs, locStart));
attrs = [];
} else if (

@@ -121,3 +130,4 @@ this.token === this.tok.T_VARIABLE ||

// reads a variable
const variables = this.read_variable_list(flags);
const variables = this.read_variable_list(flags, attrs);
attrs = [];
this.expect(";");

@@ -147,3 +157,3 @@ this.next();

*/
read_variable_list: function (flags) {
read_variable_list: function (flags, attrs) {
const result = this.node("propertystatement");

@@ -168,9 +178,15 @@

if (this.token === ";" || this.token === ",") {
return result(propName, null, nullable, type);
return result(propName, null, nullable, type, attrs || []);
} else if (this.token === "=") {
// https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L815
return result(propName, this.next().read_expr(), nullable, type);
return result(
propName,
this.next().read_expr(),
nullable,
type,
attrs || []
);
} else {
this.expect([",", ";", "="]);
return result(propName, null, nullable, type);
return result(propName, null, nullable, type, attrs || []);
}

@@ -189,3 +205,3 @@ },

*/
read_constant_list: function (flags) {
read_constant_list: function (flags, attrs) {
if (this.expect(this.tok.T_CONST)) {

@@ -227,3 +243,3 @@ this.next();

return result(null, items, flags);
return result(null, items, flags, attrs || []);
},

@@ -323,3 +339,3 @@ /*

}
let type = this.read_type();
let type = this.read_types();
if (nullable && !type) {

@@ -354,3 +370,3 @@ this.raiseError(

*/
read_interface_declaration_statement: function () {
read_interface_declaration_statement: function (attrs) {
const result = this.node("interface");

@@ -370,3 +386,3 @@ if (this.token !== this.tok.T_INTERFACE) {

const body = this.next().read_interface_body();
return result(propName, propExtends, body);
return result(propName, propExtends, body, attrs || []);
},

@@ -380,3 +396,4 @@ /*

read_interface_body: function () {
let result = [];
let result = [],
attrs = [];

@@ -394,2 +411,5 @@ while (this.token !== this.EOF && this.token !== "}") {

const locStart = this.position();
attrs = this.read_attr_list();
// read member flags

@@ -400,3 +420,3 @@ const flags = this.read_member_flags(true);

if (this.token == this.tok.T_CONST) {
const constants = this.read_constant_list(flags);
const constants = this.read_constant_list(flags, attrs);
if (this.expect(";")) {

@@ -406,5 +426,11 @@ this.next();

result = result.concat(constants);
attrs = [];
} else if (this.token === this.tok.T_FUNCTION) {
// reads a function
const method = this.read_function_declaration(2, flags);
const method = this.read_function_declaration(
2,
flags,
attrs,
locStart
);
method.parseFlags(flags);

@@ -415,2 +441,3 @@ result.push(method);

}
attrs = [];
} else {

@@ -417,0 +444,0 @@ // raise an error

@@ -228,3 +228,5 @@ /**

read_expr_item: function () {
let result, expr;
let result,
expr,
attrs = [];
if (this.token === "+")

@@ -279,2 +281,3 @@ return this.node("unary")("+", this.next().read_expr());

if (!hasItem) {
/* istanbul ignore next */
this.raiseError(

@@ -297,2 +300,3 @@ "Fatal Error : Cannot use empty list on line " +

// error fallback : list($a, $b);
/* istanbul ignore next */
return result(assignList, false);

@@ -305,2 +309,6 @@ }

if (this.token === this.tok.T_ATTRIBUTE) {
attrs = this.read_attr_list();
}
if (this.token === this.tok.T_CLONE)

@@ -327,2 +335,5 @@ return this.node("clone")(this.next().read_expr());

return this.read_internal_functions_in_yacc();
case this.tok.T_MATCH:
return this.read_match_expression();
case this.tok.T_INT_CAST:

@@ -351,2 +362,10 @@ return this.read_expr_cast("int");

case this.tok.T_THROW: {
if (this.version < 800) {
this.raiseError("PHP 8+ is required to use throw as an expression");
}
const result = this.node("throw");
const expr = this.next().read_expr();
return result(expr);
}
case this.tok.T_EXIT: {

@@ -388,3 +407,3 @@ const useDie = this.lexer.yytext.toLowerCase() === "die";

case this.tok.T_FUNCTION:
return this.read_inline_function();
return this.read_inline_function(undefined, attrs);

@@ -399,3 +418,3 @@ case this.tok.T_STATIC: {

// handles static function
return this.read_inline_function([0, 1, 0]);
return this.read_inline_function([0, 1, 0], attrs);
} else {

@@ -574,5 +593,7 @@ // rollback

*/
read_inline_function: function (flags) {
read_inline_function: function (flags, attrs) {
if (this.token === this.tok.T_FUNCTION) {
return this.read_function(true, flags);
const result = this.read_function(true, flags, attrs);
result.attrGroups = attrs;
return result;
}

@@ -600,7 +621,7 @@ // introduced in PHP 7.4

}
returnType = this.read_type();
returnType = this.read_types();
}
if (this.expect(this.tok.T_DOUBLE_ARROW)) this.next();
const body = this.read_expr();
return node(
const result = node(
params,

@@ -613,4 +634,84 @@ isRef,

);
result.attrGroups = attrs;
return result;
},
read_match_expression: function () {
const node = this.node("match");
this.expect(this.tok.T_MATCH) && this.next();
if (this.version < 800) {
this.raiseError("Match statements are not allowed before PHP 8");
}
let cond = null;
let arms = [];
if (this.expect("(")) this.next();
cond = this.read_expr();
if (this.expect(")")) this.next();
if (this.expect("{")) this.next();
arms = this.read_match_arms();
if (this.expect("}")) this.next();
return node(cond, arms);
},
read_match_arms: function () {
return this.read_list(() => this.read_match_arm(), ",", true);
},
read_match_arm: function () {
if (this.token === "}") {
return;
}
return this.node("matcharm")(this.read_match_arm_conds(), this.read_expr());
},
read_match_arm_conds: function () {
let conds = [];
if (this.token === this.tok.T_DEFAULT) {
conds = null;
this.next();
} else {
conds.push(this.read_expr());
while (this.token === ",") {
this.next();
if (this.token === this.tok.T_DOUBLE_ARROW) {
this.next();
return conds;
}
conds.push(this.read_expr());
}
}
if (this.expect(this.tok.T_DOUBLE_ARROW)) {
this.next();
}
return conds;
},
read_attribute() {
const name = this.text();
let args = [];
this.next();
if (this.token === "(") {
args = this.read_argument_list();
}
return this.node("attribute")(name, args);
},
read_attr_list() {
const list = [];
if (this.token === this.tok.T_ATTRIBUTE) {
do {
const attrGr = this.node("attrgroup")([]);
this.next();
attrGr.attrs.push(this.read_attribute());
while (this.token === ",") {
this.next();
if (this.token !== "]") attrGr.attrs.push(this.read_attribute());
}
list.push(attrGr);
this.expect("]");
this.next();
} while (this.token === this.tok.T_ATTRIBUTE);
}
return list;
},
/*

@@ -626,2 +727,3 @@ * ```ebnf

let args = [];
const attrs = this.read_attr_list();
if (this.token === this.tok.T_CLASS) {

@@ -639,6 +741,5 @@ const what = this.node("class");

}
return result(
what(null, propExtends, propImplements, body, [0, 0, 0]),
args
);
const whatNode = what(null, propExtends, propImplements, body, [0, 0, 0]);
whatNode.attrGroups = attrs;
return result(whatNode, args);
}

@@ -645,0 +746,0 @@ // Already existing class

@@ -35,6 +35,8 @@ /**

*/
read_function: function (closure, flag) {
read_function: function (closure, flag, attrs, locStart) {
const result = this.read_function_declaration(
closure ? 1 : flag ? 2 : 0,
flag && flag[1] === 1
flag && flag[1] === 1,
attrs || [],
locStart
);

@@ -66,3 +68,3 @@ if (flag && flag[2] == 1) {

*/
read_function_declaration: function (type, isStatic) {
read_function_declaration: function (type, isStatic, attrs, locStart) {
let nodeName = "function";

@@ -133,9 +135,28 @@ if (type === 1) {

}
returnType = this.read_type();
returnType = this.read_types();
}
const apply_attrgroup_location = (node) => {
node.attrGroups = attrs || [];
if (locStart && node.loc) {
node.loc.start = locStart;
if (node.loc.source) {
node.loc.source = this.lexer._input.substr(
node.loc.start.offset,
node.loc.end.offset - node.loc.start.offset
);
}
}
return node;
};
if (type === 1) {
// closure
return result(params, isRef, use, returnType, nullable, isStatic);
return apply_attrgroup_location(
result(params, isRef, use, returnType, nullable, isStatic)
);
}
return result(name, params, isRef, returnType, nullable);
return apply_attrgroup_location(
result(name, params, isRef, returnType, nullable)
);
},

@@ -156,4 +177,24 @@

read_list_with_dangling_comma: function (item) {
const result = [];
while (this.token != this.EOF) {
result.push(item());
if (this.token == ",") {
this.next();
if (this.version >= 800 && this.token === ")") {
return result;
}
} else if (this.token == ")") {
break;
} else {
this.error([",", ")"]);
break;
}
}
return result;
},
read_lexical_var_list: function () {
return this.read_list(this.read_lexical_var, ",");
return this.read_list_with_dangling_comma(this.read_lexical_var.bind(this));
},

@@ -183,17 +224,6 @@

read_parameter_list: function () {
const result = [];
if (this.token != ")") {
while (this.token != this.EOF) {
result.push(this.read_parameter());
if (this.token == ",") {
this.next();
} else if (this.token == ")") {
break;
} else {
this.error([",", ")"]);
break;
}
}
return this.read_list_with_dangling_comma(this.read_parameter.bind(this));
}
return result;
return [];
},

@@ -210,4 +240,7 @@ /*

let value = null;
let type = null;
let types = null;
let nullable = false;
let attrs = [];
if (this.token === this.tok.T_ATTRIBUTE) attrs = this.read_attr_list();
const flags = this.read_promoted();
if (this.token === "?") {

@@ -217,4 +250,4 @@ this.next();

}
type = this.read_type();
if (nullable && !type) {
types = this.read_types();
if (nullable && !types) {
this.raiseError(

@@ -235,4 +268,47 @@ "Expecting a type definition combined with nullable operator"

}
return node(parameterName, type, value, isRef, isVariadic, nullable);
const result = node(
parameterName,
types,
value,
isRef,
isVariadic,
nullable,
flags
);
if (attrs) result.attrGroups = attrs;
return result;
},
read_types() {
const types = [];
const unionType = this.node("uniontype");
let type = this.read_type();
if (!type) return null;
types.push(type);
while (this.token === "|") {
this.next();
type = this.read_type();
types.push(type);
}
if (types.length === 1) {
return types[0];
} else {
return unionType(types);
}
},
read_promoted() {
const MODIFIER_PUBLIC = 1;
const MODIFIER_PROTECTED = 2;
const MODIFIER_PRIVATE = 4;
if (this.token === this.tok.T_PUBLIC) {
this.next();
return MODIFIER_PUBLIC;
} else if (this.token === this.tok.T_PROTECTED) {
this.next();
return MODIFIER_PROTECTED;
} else if (this.token === this.tok.T_PRIVATE) {
this.next();
return MODIFIER_PRIVATE;
}
return 0;
},
/*

@@ -277,3 +353,3 @@ * Reads a list of arguments

* ```ebnf
* argument_list ::= T_ELLIPSIS? expr
* argument_list ::= T_STRING ':' expr | T_ELLIPSIS? expr
* ```

@@ -285,2 +361,19 @@ */

}
if (
this.token === this.tok.T_STRING ||
Object.values(this.lexer.keywords).includes(this.token)
) {
const lexerState = this.lexer.getState();
const nextToken = this.lexer.lex();
this.lexer.setState(lexerState);
if (nextToken === ":") {
if (this.version < 800) {
this.raiseError("PHP 8+ is required to use named arguments");
}
return this.node("namedargument")(
this.text(),
this.next().next().read_expr()
);
}
}
return this.read_expr();

@@ -300,3 +393,6 @@ },

return result("typereference", type.toLowerCase(), type);
} else if (this.token === this.tok.T_STRING) {
} else if (
this.token === this.tok.T_STRING ||
this.token === this.tok.T_STATIC
) {
const type = this.text();

@@ -303,0 +399,0 @@ const backup = [this.token, this.lexer.getState()];

@@ -40,5 +40,9 @@ /**

read_top_statement: function () {
let attrs = [];
if (this.token === this.tok.T_ATTRIBUTE) {
attrs = this.read_attr_list();
}
switch (this.token) {
case this.tok.T_FUNCTION:
return this.read_function(false, false);
return this.read_function(false, false, attrs);
// optional flags

@@ -48,5 +52,5 @@ case this.tok.T_ABSTRACT:

case this.tok.T_CLASS:
return this.read_class_declaration_statement();
return this.read_class_declaration_statement(attrs);
case this.tok.T_INTERFACE:
return this.read_interface_declaration_statement();
return this.read_interface_declaration_statement(attrs);
case this.tok.T_TRAIT:

@@ -155,5 +159,12 @@ return this.read_trait_declaration_statement();

read_inner_statement: function () {
let attrs = [];
if (this.token === this.tok.T_ATTRIBUTE) {
attrs = this.read_attr_list();
}
switch (this.token) {
case this.tok.T_FUNCTION:
return this.read_function(false, false);
case this.tok.T_FUNCTION: {
const result = this.read_function(false, false);
result.attrGroups = attrs;
return result;
}
// optional flags

@@ -160,0 +171,0 @@ case this.tok.T_ABSTRACT:

@@ -13,3 +13,3 @@ /**

* (
* T_CATCH '(' namespace_name variable ')' '{' inner_statement* '}'
* T_CATCH '(' namespace_name (variable)? ')' '{' inner_statement* '}'
* )*

@@ -32,3 +32,6 @@ * (T_FINALLY '{' inner_statement* '}')?

const what = this.read_list(this.read_namespace_name, "|", false);
const variable = this.read_variable(true, false);
let variable = null;
if (this.version < 800 || this.token === this.tok.T_VARIABLE) {
variable = this.read_variable(true, false);
}
this.expect(")");

@@ -35,0 +38,0 @@ catches.push(item(this.next().read_statement(), what, variable));

@@ -17,2 +17,3 @@ /**

const items = [];
/* istanbul ignore next */
if (this.expect(":")) this.next();

@@ -29,2 +30,3 @@ while (this.token != this.EOF && this.token !== token) {

}
/* istanbul ignore next */
if (this.expect(token)) this.next();

@@ -155,2 +157,3 @@ this.expectEndOfStatement();

// plain variable name
/* istanbul ignore else */
if (this.expect(this.tok.T_VARIABLE)) {

@@ -157,0 +160,0 @@ const name = this.text().substring(1);

@@ -231,2 +231,7 @@ /**

}
case this.tok.T_NULLSAFE_OBJECT_OPERATOR: {
node = this.node("nullsafepropertylookup");
result = node(result, this.read_what());
break;
}
default:

@@ -233,0 +238,0 @@ break recursive_scan_loop;

@@ -9,145 +9,2 @@ /**

/**
* @memberOf module:php-parser
* @readonly
* @enum
*/
const TokenNames = {
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,
T_COALESCE_EQUAL: 234,
T_FN: 235,
};
/**
* PHP AST Tokens

@@ -298,6 +155,148 @@ * @readonly

235: "T_FN",
236: "T_NULLSAFE_OBJECT_OPERATOR",
237: "T_MATCH",
238: "T_ATTRIBUTE",
},
names: TokenNames,
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,
T_COALESCE_EQUAL: 234,
T_FN: 235,
T_NULLSAFE_OBJECT_OPERATOR: 236,
T_MATCH: 237,
T_ATTRIBUTE: 238,
},
};
module.exports = Object.freeze(tokens);

@@ -132,3 +132,3 @@ declare module "php-parser" {

extends: Identifier | null;
implements: Identifier[];
implements: Identifier[] | null;
body: Declaration[];

@@ -264,3 +264,3 @@ isAnonymous: boolean;

test: Expression;
body: Statement;
body: Statement | null;
}

@@ -402,3 +402,3 @@ /**

increment: Expression[];
body: Statement;
body: Statement | null;
shortForm: boolean;

@@ -413,3 +413,3 @@ }

value: Expression;
body: Statement;
body: Statement | null;
shortForm: boolean;

@@ -707,2 +707,4 @@ }

properties: Property[];
visibility: string|null;
isStatic: boolean;
}

@@ -824,3 +826,3 @@ /**

catches: Catch[];
allways: Block;
always: Block;
}

@@ -913,3 +915,3 @@ /**

test: Expression;
body: Statement;
body: Statement | null;
shortForm: boolean;

@@ -1000,3 +1002,3 @@ }

*/
tokenGetAll(buffer: string): String[];
tokenGetAll(buffer: string): (string | string[])[];
lexer: Lexer;

@@ -1003,0 +1005,0 @@ parser: Parser;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc