Skip to content

Experiment: Use native php tests #956

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 26 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
8d82aca
Add submodule with php-src.
May 30, 2022
f4aab9e
Merge pull request #941 from czosel/fix-enum-as-identifier-2
MaartenStaa May 30, 2022
fb2f446
3.1.0-beta.9
czosel May 30, 2022
243b0ee
Automatically generate Jest tests from .phpt files in php-src.
May 31, 2022
ca061f4
Handle nuances with whitespace and use statements.
May 31, 2022
12b4813
Start differentiating between namespace_name and name.
May 31, 2022
2cc3fa9
Handle new expression such as `new ('std' . 'Class')`.
May 31, 2022
5b9a744
Handle nullsafe object operator on arbitrary expressions, like `[]?->…
May 31, 2022
c3c8ee4
Mark some tests as throwing a parse error.
May 31, 2022
c1636cd
Disallow static type in argument lists.
May 31, 2022
5ac08bf
Throw error on unterminated multi-line comment.
Jun 2, 2022
af231be
Fix error on variadic function calls.
Jun 7, 2022
424b271
Fix lexing of octal literals.
Jun 8, 2022
1058cad
Move php-src tests to their own files.
Jun 8, 2022
9821921
Fix parsing of enum cases with attributes.
Jun 8, 2022
9ce6b94
Merge pull request #949 from glayzzle/fix-unpacking-multiple-arguments
czosel Jun 10, 2022
71c2a9f
chore: upgrade dependencies
czosel Jun 10, 2022
6736591
Merge pull request #951 from czosel/upgrade-deps
czosel Jun 10, 2022
13cc2b6
3.1.0-beta.10
czosel Jun 10, 2022
bbc70fd
Update php-src test files.
Jun 14, 2022
d66c5c8
Be more conservative about which .phpt files we use.
Jun 14, 2022
c722794
Merge branch 'main' into use-native-php-tests
Jun 14, 2022
b42b8ce
New snapshots after merge.
Jun 14, 2022
8640f86
Mark php-src as failing.
Jun 14, 2022
4dab16d
Mark php-src tests as failing.
Jun 14, 2022
e9ac21e
Mark php-src tests as not failing.
Jun 14, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "test/php-src"]
path = php-src
url = https://github.com/php/php-src
190 changes: 190 additions & 0 deletions bin/generate-php-src-tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
#!/usr/bin/env node
const fs = require("fs");
const glob = require("glob");

// Note: Ideally we'd check for "--EXPECTF--" in the phpt file, but that also
// described run-time errors, rather than just parse errors.
const testsThatExpectParseErrors = [
"Zend/tests/attributes/019_variable_attribute_name.phpt",
"Zend/tests/bug43343.phpt",
"Zend/tests/bug60099.phpt",
"Zend/tests/bug64660.phpt",
"Zend/tests/bug70430.phpt",
"Zend/tests/bug76439_2.phpt",
"Zend/tests/bug77993.phpt",
"Zend/tests/bug78363.phpt",
"Zend/tests/bug78454_1.phpt",
"Zend/tests/bug78454_2.phpt",
"Zend/tests/ctor_promotion_additional_modifiers.phpt",
"Zend/tests/flexible-heredoc-error1.phpt",
"Zend/tests/flexible-heredoc-error10.phpt",
"Zend/tests/flexible-heredoc-error11.phpt",
"Zend/tests/flexible-heredoc-error12.phpt",
"Zend/tests/flexible-heredoc-error13.phpt",
"Zend/tests/flexible-heredoc-error2.phpt",
"Zend/tests/flexible-heredoc-error3.phpt",
"Zend/tests/flexible-heredoc-error4.phpt",
"Zend/tests/flexible-heredoc-error5.phpt",
"Zend/tests/flexible-heredoc-error6.phpt",
"Zend/tests/flexible-heredoc-error7.phpt",
"Zend/tests/flexible-heredoc-error8.phpt",
"Zend/tests/flexible-heredoc-error9.phpt",
"Zend/tests/flexible-nowdoc-error1.phpt",
"Zend/tests/flexible-nowdoc-error2.phpt",
"Zend/tests/flexible-nowdoc-error3.phpt",
"Zend/tests/flexible-nowdoc-error4.phpt",
"Zend/tests/flexible-nowdoc-error5.phpt",
"Zend/tests/flexible-nowdoc-error6.phpt",
"Zend/tests/flexible-nowdoc-error7.phpt",
"Zend/tests/flexible-nowdoc-error8.phpt",
"Zend/tests/function_arguments/call_with_leading_comma_error.phpt",
"Zend/tests/function_arguments/call_with_multi_inner_comma_error.phpt",
"Zend/tests/function_arguments/call_with_multi_trailing_comma_error.phpt",
"Zend/tests/function_arguments/call_with_only_comma_error.phpt",
"Zend/tests/function_arguments_001.phpt",
"Zend/tests/function_arguments_002.phpt",
"Zend/tests/grammar/bug78441.phpt",
"Zend/tests/grammar/regression_004.phpt",
"Zend/tests/grammar/regression_005.phpt",
"Zend/tests/grammar/regression_010.phpt",
"Zend/tests/grammar/regression_012.phpt",
"Zend/tests/heredoc_005.phpt",
"Zend/tests/heredoc_013.phpt",
"Zend/tests/heredoc_014.phpt",
"Zend/tests/list_011.phpt",
"Zend/tests/lsb_008.phpt",
"Zend/tests/lsb_009.phpt",
"Zend/tests/namespace_name_namespace_start.phpt",
"Zend/tests/namespaced_name_whitespace.phpt",
"Zend/tests/ns_088.phpt",
"Zend/tests/ns_094.phpt",
"Zend/tests/ns_096.phpt",
"Zend/tests/ns_trailing_comma_error_01.phpt",
"Zend/tests/ns_trailing_comma_error_02.phpt",
"Zend/tests/ns_trailing_comma_error_03.phpt",
"Zend/tests/ns_trailing_comma_error_04.phpt",
"Zend/tests/ns_trailing_comma_error_05.phpt",
"Zend/tests/ns_trailing_comma_error_06.phpt",
"Zend/tests/ns_trailing_comma_error_07.phpt",
"Zend/tests/ns_trailing_comma_error_08.phpt",
"Zend/tests/numeric_literal_separator_002.phpt",
"Zend/tests/numeric_literal_separator_003.phpt",
"Zend/tests/numeric_literal_separator_004.phpt",
"Zend/tests/numeric_literal_separator_005.phpt",
"Zend/tests/numeric_literal_separator_006.phpt",
"Zend/tests/numeric_literal_separator_007.phpt",
"Zend/tests/numeric_literal_separator_008.phpt",
"Zend/tests/numeric_literal_separator_009.phpt",
"Zend/tests/oct_whitespace.phpt",
"Zend/tests/readonly_classes/readonly_enum.phpt",
"Zend/tests/readonly_classes/readonly_interface.phpt",
"Zend/tests/readonly_classes/readonly_trait.phpt",
"Zend/tests/short_echo_as_identifier.phpt",
"Zend/tests/traits/bug55524.phpt",
"Zend/tests/traits/bugs/interfaces.phpt",
"Zend/tests/type_declarations/intersection_types/invalid_types/invalid_nullable_type.phpt",
"Zend/tests/type_declarations/intersection_types/parse_error.phpt",
"Zend/tests/type_declarations/intersection_types/parse_error.phpt",
"Zend/tests/type_declarations/mixed/casting/mixed_cast_error.phpt",
"Zend/tests/type_declarations/static_type_param.phpt",
"Zend/tests/type_declarations/static_type_property.phpt",
"Zend/tests/type_declarations/typed_properties_025.phpt",
"Zend/tests/unterminated_comment.phpt",
"Zend/tests/varSyntax/globalNonSimpleVariableError.phpt",
"tests/classes/constants_error_006.phpt",
"tests/classes/constants_error_007.phpt",
"tests/lang/019.phpt",
"tests/lang/bug21669.phpt",
"tests/lang/bug21820.phpt",
"tests/lang/bug71897.phpt",
"tests/lang/invalid_octal.phpt",
"tests/lang/string/unicode_escape_empty.phpt",
"tests/lang/string/unicode_escape_incomplete.phpt",
"tests/lang/string/unicode_escape_large_codepoint.phpt",
"tests/lang/string/unicode_escape_sign.phpt",
"tests/lang/string/unicode_escape_sign2.phpt",
"tests/lang/string/unicode_escape_whitespace.phpt",

// These should also throw parse errors according to PHP 8.1, but we also
// support older versions.
// "Zend/tests/real_cast.phpt",

// These are not parse errors in PHP strictly speaking, but they test syntax
// that is still invalid (i.e. it generates a fatal error).
"Zend/tests/enum/case-in-class.phpt",
"Zend/tests/enum/no-name-property.phpt",
"Zend/tests/enum/no-properties.phpt",
"Zend/tests/errmsg_001.phpt",
"Zend/tests/readonly_props/readonly_const.phpt",
"Zend/tests/readonly_props/readonly_method.phpt",
"Zend/tests/readonly_props/readonly_method_trait.phpt",
"Zend/tests/static_in_trait_insteadof_list.phpt",
"Zend/tests/variadic/only_last_error.phpt",
];

const header = `// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {`;

const footer = `});
`;

for (const absolutePath of glob.sync(
__dirname + "/../php-src/{tests,Zend,ext/standard}/**/*.phpt"
)) {
const relativePath = absolutePath.substring(
absolutePath.indexOf("php-src") + "php-src/".length
);
const testName = [];
const testContents = [];
const expectError = testsThatExpectParseErrors.includes(relativePath);
let testFileName = relativePath.replace(/[/\\]/g, "-");
testFileName = testFileName.substring(0, testFileName.lastIndexOf("."));

let section = null;
for (const line of fs
.readFileSync(absolutePath)
.toString()
.split(/[\r\n]+/)) {
if (/^--\w/.test(line)) {
if (line === "--TEST--") {
section = "name";
} else if (line === "--FILE--") {
section = "file";
} else {
section = null;
}
continue;
}

if (section === "name") {
testName.push(line);
} else if (section === "file") {
testContents.push(line);
}
// TODO: Handle --FILE_EXTERNAL--
}

if (testContents.length === 0) {
continue;
}

const contents = `${header}
// ${relativePath}
it(${JSON.stringify(testName.join("\n"))}, function () {
expect(${expectError ? "() => " : ""}parser.parseCode(${JSON.stringify(
testContents.join("\n")
)})).${expectError ? "toThrowErrorMatchingSnapshot" : "toMatchSnapshot"}();
});
${footer}`;

fs.writeFile(
`${__dirname}/../test/php-src/${testFileName}.test.js`,
contents,
(err) => {
if (err) throw err;
console.log(`Written ${testFileName}`);
}
);
}
2 changes: 2 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -25,6 +25,8 @@ module.exports = {
testPathIgnorePatterns: [
"<rootDir>/node_modules/",
"<rootDir>/coverage/",
"<rootDir>/php-src/",
"<rootDir>/test/php-src/",
],
},
],
15 changes: 8 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "php-parser",
"version": "3.1.0-beta.8",
"version": "3.1.0-beta.10",
"description": "Parse PHP code from JS and returns its AST",
"main": "src/index.js",
"browser": "dist/php-parser.js",
@@ -62,23 +62,24 @@
],
"license": "BSD-3-Clause",
"devDependencies": {
"@babel/core": "^7.18.0",
"@babel/preset-env": "^7.18.0",
"@babel/core": "^7.18.2",
"@babel/preset-env": "^7.18.2",
"babel-loader": "^8.0.5",
"benchmark": "^2.1.4",
"coveralls": "^3.0.3",
"eslint": "^8.16.0",
"eslint-plugin-jest": "^26.2.2",
"eslint": "^8.17.0",
"eslint-plugin-jest": "^26.5.3",
"eslint-plugin-prettier": "^4.0.0",
"glob": "^8.0.3",
"husky": "^8.0.1",
"jest": "^28.1.0",
"jest": "^28.1.1",
"jest-runner-eslint": "^1.0.1",
"jsdoc": "^3.6.10",
"jsdoc-template": "^1.2.0",
"lodash.template": ">=4.5.0",
"prettier": "^2.6.2",
"tsd-jsdoc": "^2.5.0",
"webpack": "^5.72.1",
"webpack": "^5.73.0",
"webpack-cli": "^4.9.2",
"yarpm": "^1.1.1"
}
1 change: 1 addition & 0 deletions php-src
Submodule php-src added at 93fc88
17 changes: 17 additions & 0 deletions src/lexer.js
Original file line number Diff line number Diff line change
@@ -211,6 +211,23 @@ Lexer.prototype.input = function () {
return ch;
};

/**
* peeks the next non-whitespace character, or null if we
* reach the end of the input
* @function Lexer#peekNonWhitespace
* @memberOf module:php-parser
*/
Lexer.prototype.peekNonWhitespace = function () {
for (let i = this.offset; i < this._input.length; i++) {
const ch = this._input[i];
if (ch !== " " && ch !== "\r" && ch !== "\n") {
return ch;
}
}

return null;
};

/**
* revert eating specified size
* @function Lexer#unput
6 changes: 4 additions & 2 deletions src/lexer/comments.js
Original file line number Diff line number Diff line change
@@ -55,9 +55,11 @@ module.exports = {
ch = this.input();
if (ch === "*" && this._input[this.offset] === "/") {
this.input();
break;
return token;
}
}
return token;

/* istanbul ignore next */
throw new Error(`Unterminated comment starting line ${this.yylineno}`);
},
};
19 changes: 18 additions & 1 deletion src/lexer/numbers.js
Original file line number Diff line number Diff line change
@@ -35,7 +35,13 @@ module.exports = {
} else {
this.unput(ch ? 2 : 1);
}
// @fixme check octal notation ? not usefull
} else if (ch === "o" || ch === "O") {
ch = this.input();
if (ch !== "_" && this.is_OCTAL()) {
return this.consume_ONUM();
} else {
this.unput(ch ? 2 : 1);
}
} else if (!this.is_NUM()) {
if (ch) this.unput(1);
}
@@ -151,4 +157,15 @@ module.exports = {
}
return this.tok.T_LNUMBER;
},
// read an octal number
consume_ONUM: function () {
while (this.offset < this.size) {
const ch = this.input();
if (!this.is_OCTAL()) {
if (ch) this.unput(1);
break;
}
}
return this.tok.T_LNUMBER;
},
};
6 changes: 2 additions & 4 deletions src/lexer/tokens.js
Original file line number Diff line number Diff line change
@@ -64,9 +64,8 @@ module.exports = {
? this.tok.T_NAME_RELATIVE
: this.tok.T_NAME_QUALIFIED;
do {
if (this._input[this.offset] === "{") {
if (this.peekNonWhitespace() === "{") {
// e.g. when using group use statements, the last '\\' is followed by a '{'
this.input();
break;
}

@@ -125,9 +124,8 @@ module.exports = {
if (this.is_LABEL_START()) {
let ch;
do {
if (this._input[this.offset] === "{") {
if (this.peekNonWhitespace() === "{") {
// e.g. when using group use statements, the last '\\' is followed by a '{'
this.input();
break;
}

10 changes: 10 additions & 0 deletions src/lexer/utils.js
Original file line number Diff line number Diff line change
@@ -99,4 +99,14 @@ module.exports = {
// else
return false;
},
// check if current char can be an octal number
is_OCTAL: function () {
const ch = this._input.charCodeAt(this.offset - 1);
// 0 - 7
if (ch > 47 && ch < 56) return true;
// _ (code 95)
if (ch === 95) return true;
// else
return false;
},
};
9 changes: 9 additions & 0 deletions src/parser.js
Original file line number Diff line number Diff line change
@@ -184,6 +184,15 @@ const Parser = function (lexer, ast) {
].map(mapIt)
),
EOS: new Map([";", this.EOF, this.tok.T_INLINE_HTML].map(mapIt)),
CLASS_NAME: new Map(
[
this.tok.T_STATIC,
this.tok.T_STRING,
this.tok.T_NAME_QUALIFIED,
this.tok.T_NAME_FULLY_QUALIFIED,
this.tok.T_NAME_RELATIVE,
].map(mapIt)
),
EXPR: new Map(
[
"@",
8 changes: 4 additions & 4 deletions src/parser/class.js
Original file line number Diff line number Diff line change
@@ -79,6 +79,10 @@ module.exports = {
continue;
}

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

// check enum cases
if (allow_enum_cases && this.token === this.tok.T_CASE) {
const enumcase = this.read_enum_case();
@@ -89,10 +93,6 @@ module.exports = {
continue;
}

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

const locStart = this.position();

// read member flags
9 changes: 8 additions & 1 deletion src/parser/expr.js
Original file line number Diff line number Diff line change
@@ -737,7 +737,9 @@ module.exports = {

/*
* ```ebnf
* new_expr ::= T_NEW (namespace_name function_argument_list) | (T_CLASS ... class declaration)
* new_expr ::=
* T_NEW (namespace_name function_argument_list)
* | (T_CLASS ... class declaration)
* ```
* https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L850
*/
@@ -797,6 +799,10 @@ module.exports = {
return result;
} else if (this.is("VARIABLE")) {
return this.read_variable(true, false);
} else if (this.token === "(") {
const result = this.read_expr();
this.expect(")");
return result;
} else {
this.expect([this.tok.T_STRING, "VARIABLE"]);
}
@@ -805,6 +811,7 @@ module.exports = {
while (this.token !== this.EOF) {
if (
this.token === this.tok.T_OBJECT_OPERATOR ||
this.token === this.tok.T_NULLSAFE_OBJECT_OPERATOR ||
this.token === this.tok.T_DOUBLE_COLON
) {
expr = this.recursive_variable_chain_scan(expr, false, false, true);
46 changes: 36 additions & 10 deletions src/parser/function.js
Original file line number Diff line number Diff line change
@@ -217,11 +217,29 @@ module.exports = {
* ```
*/
read_parameter_list: function (is_class_constructor) {
if (this.token != ")") {
if (this.token !== ")") {
let wasVariadic = false;

return this.read_list_with_dangling_comma(
this.read_parameter.bind(this, is_class_constructor)
function () {
const parameter = this.read_parameter(is_class_constructor);
if (parameter) {
// variadic parameters can only be defined at the end of the parameter list
if (wasVariadic) {
this.raiseError(
"Unexpected parameter after a variadic parameter"
);
}
if (parameter.variadic) {
wasVariadic = true;
}
}
return parameter;
}.bind(this),
","
);
}

return [];
},
/*
@@ -256,7 +274,7 @@ module.exports = {
this.next();
nullable = true;
}
types = this.read_types();
types = this.read_types(false);
if (nullable && !types) {
this.raiseError(
"Expecting a type definition combined with nullable operator"
@@ -286,14 +304,14 @@ module.exports = {
if (attrs) result.attrGroups = attrs;
return result;
},
read_types() {
read_types(allowStatic = true) {
const MODE_UNSET = "unset";
const MODE_UNION = "union";
const MODE_INTERSECTION = "intersection";

const types = [];
let mode = MODE_UNSET;
const type = this.read_type();
const type = this.read_type(allowStatic);
if (!type) return null;

// we have matched a single type
@@ -388,10 +406,14 @@ module.exports = {
function () {
const argument = this.read_argument();
if (argument) {
if (wasVariadic) {
this.raiseError("Unexpected argument after a variadic argument");
const isVariadic = argument.kind === "variadic";
// variadic arguments can only be followed by other variadic arguments
if (wasVariadic && !isVariadic) {
this.raiseError(
"Unexpected non-variadic argument after a variadic argument"
);
}
if (argument.kind === "variadic") {
if (isVariadic) {
wasVariadic = true;
}
}
@@ -432,7 +454,7 @@ module.exports = {
* type ::= T_ARRAY | T_CALLABLE | namespace_name
* ```
*/
read_type: function () {
read_type: function (allowStatic = true) {
const result = this.node();
if (this.token === this.tok.T_ARRAY || this.token === this.tok.T_CALLABLE) {
const type = this.text();
@@ -443,7 +465,7 @@ module.exports = {
this.token === this.tok.T_NAME_QUALIFIED ||
this.token === this.tok.T_NAME_FULLY_QUALIFIED ||
this.token === this.tok.T_STRING ||
this.token === this.tok.T_STATIC
(allowStatic && this.token === this.tok.T_STATIC)
) {
const type = this.text();
const backup = [this.token, this.lexer.getState()];
@@ -462,6 +484,10 @@ module.exports = {
return this.read_namespace_name();
}
}
if (!allowStatic && this.token === this.tok.T_STATIC) {
this.error();
this.next(); // graceful mode
}
// fix : destroy not consumed node (release comments)
result.destroy();
return null;
67 changes: 64 additions & 3 deletions src/parser/namespace.js
Original file line number Diff line number Diff line change
@@ -122,7 +122,9 @@ module.exports = {
items.push(this.read_use_declaration(false));
if (this.token === ",") {
items = items.concat(this.next().read_use_declarations(false));
} else if (this.token === "{") {
} else if (this.token === this.tok.T_NS_SEPARATOR) {
this.next();
this.expect("{");
name = items[0].name;
items = this.next().read_use_declarations(type === null);
this.expect("}") && this.next();
@@ -131,13 +133,72 @@ module.exports = {
this.expect(";") && this.next();
return result;
},
read_class_name: function () {
if (this.token === this.tok.T_STATIC) {
const result = this.node("staticreference");
const raw = this.text();
this.next();
return result(raw);
}

return this.read_name();
},
read_name: function () {
this.expect([
this.tok.T_STRING,
this.tok.T_NAME_QUALIFIED,
this.tok.T_NAME_FULLY_QUALIFIED,
this.tok.T_NAME_RELATIVE,
]);

const result = this.node();
let resolution;
let name = this.text();
switch (this.token) {
case this.tok.T_NAME_RELATIVE:
resolution = this.ast.name.RELATIVE_NAME;
name = name.replace(/^namespace\\/, "");
break;
case this.tok.T_NAME_QUALIFIED:
resolution = this.ast.name.QUALIFIED_NAME;
break;
case this.tok.T_NAME_FULLY_QUALIFIED:
resolution = this.ast.name.FULL_QUALIFIED_NAME;
break;
default:
resolution = this.ast.name.UNQUALIFIED_NAME;
if (!this.expect(this.tok.T_STRING)) {
// graceful mode
return result("name", "", this.ast.name.FULL_QUALIFIED_NAME);
}
}

this.next();

if (this.token !== "(") {
if (name.toLowerCase() === "parent") {
return result("parentreference", name);
} else if (name.toLowerCase() === "self") {
return result("selfreference", name);
}
}

return result("name", name, resolution);
},
/*
*
* @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1045
*/
read_class_name_reference: function () {
// resolved as the same
return this.read_variable(true, false);
if (this.is("CLASS_NAME")) {
return this.read_class_name();
} else if (this.token === "(") {
const result = this.read_expr();
this.expect(")");
return result;
} else {
return this.read_variable(true, false);
}
},
/*
* Reads a use declaration
2 changes: 1 addition & 1 deletion src/parser/try.js
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ module.exports = {
while (this.token === this.tok.T_CATCH) {
const item = this.node("catch");
this.next().expect("(") && this.next();
const what = this.read_list(this.read_namespace_name, "|", false);
const what = this.read_list(this.read_name, "|", false);
let variable = null;
if (this.version < 800 || this.token === this.tok.T_VARIABLE) {
variable = this.read_variable(true, false);
2 changes: 1 addition & 1 deletion src/parser/utils.js
Original file line number Diff line number Diff line change
@@ -113,7 +113,7 @@ module.exports = {
* @return {Reference[]}
*/
read_name_list: function () {
return this.read_list(this.read_namespace_name, ",", false);
return this.read_list(this.read_name, ",", false);
},

/*
2 changes: 1 addition & 1 deletion src/parser/variable.js
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ module.exports = {
])
) {
result = this.node();
const name = this.read_namespace_name();
const name = this.read_name();
if (
this.token != this.tok.T_DOUBLE_COLON &&
this.token != "(" &&
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-001.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/001.phpt
it("func_num_args() tests", function () {
expect(parser.parseCode("<?php\nfunction test1() {\n var_dump(func_num_args());\n}\nfunction test2($a) {\n var_dump(func_num_args());\n}\nfunction test3($a, $b) {\n var_dump(func_num_args());\n}\ntest1();\ntest2(1);\ntry {\n test2();\n} catch (Throwable $e) {\n echo \"Exception: \" . $e->getMessage() . \"\\n\";\n}\ntest3(1,2);\ncall_user_func(\"test1\");\ntry {\n call_user_func(\"test3\", 1);\n} catch (Throwable $e) {\n echo \"Exception: \" . $e->getMessage() . \"\\n\";\n}\ncall_user_func(\"test3\", 1, 2);\nclass test {\n static function test1($a) {\n var_dump(func_num_args());\n }\n}\ntest::test1(1);\ntry {\n func_num_args();\n} catch (Error $exception) {\n echo $exception->getMessage() . \"\\n\";\n}\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-002.test.js
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-003.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/003.phpt
it("func_get_args() tests", function () {
expect(parser.parseCode("<?php\nfunction test1() {\n var_dump(func_get_args());\n}\nfunction test2($a) {\n var_dump(func_get_args());\n}\nfunction test3($a, $b) {\n var_dump(func_get_args());\n}\ntest1();\ntest1(10);\ntest2(1);\ntry {\n test2();\n} catch (Throwable $e) {\n echo \"Exception: \" . $e->getMessage() . \"\\n\";\n}\ntest3(1,2);\ncall_user_func(\"test1\");\ntry {\n call_user_func(\"test3\", 1);\n} catch (Throwable $e) {\n echo \"Exception: \" . $e->getMessage() . \"\\n\";\n}\ncall_user_func(\"test3\", 1, 2);\nclass test {\n static function test1($a) {\n var_dump(func_get_args());\n }\n}\ntest::test1(1);\ntry {\n var_dump(func_get_args());\n} catch (\\Error $e) {\n echo $e->getMessage() . \\PHP_EOL;\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-004.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/004.phpt
it("strncmp() tests", function () {
expect(parser.parseCode("<?php\nvar_dump(strncmp(\"\", \"\", 100));\ntry {\n var_dump(strncmp(\"aef\", \"dfsgbdf\", -1));\n} catch (\\ValueError $e) {\n echo $e->getMessage() . \\PHP_EOL;\n}\nvar_dump(strncmp(\"fghjkl\", \"qwer\", 0));\nvar_dump(strncmp(\"qwerty\", \"qwerty123\", 6));\nvar_dump(strncmp(\"qwerty\", \"qwerty123\", 7));\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-005.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/005.phpt
it("strcasecmp() tests", function () {
expect(parser.parseCode("<?php\nvar_dump(strcasecmp(\"\", \"\"));\nvar_dump(strcasecmp(\"aef\", \"dfsgbdf\"));\nvar_dump(strcasecmp(\"qwe\", \"qwer\"));\nvar_dump(strcasecmp(\"qwerty\", \"QweRty\"));\nvar_dump(strcasecmp(\"qwErtY\", \"qwerty\"));\nvar_dump(strcasecmp(\"q123\", \"Q123\"));\nvar_dump(strcasecmp(\"01\", \"01\"));\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-006.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/006.phpt
it("strncasecmp() tests", function () {
expect(parser.parseCode("<?php\ntry {\n var_dump(strncasecmp(\"\", \"\", -1));\n} catch (\\ValueError $e) {\n echo $e->getMessage() . \\PHP_EOL;\n}\nvar_dump(strncasecmp(\"aef\", \"dfsgbdf\", 0));\nvar_dump(strncasecmp(\"aef\", \"dfsgbdf\", 10));\nvar_dump(strncasecmp(\"qwe\", \"qwer\", 3));\nvar_dump(strncasecmp(\"qwerty\", \"QweRty\", 6));\nvar_dump(strncasecmp(\"qwErtY\", \"qwer\", 7));\nvar_dump(strncasecmp(\"q123\", \"Q123\", 3));\nvar_dump(strncasecmp(\"01\", \"01\", 1000));\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-008.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/008.phpt
it("define() tests", function () {
expect(parser.parseCode("<?php\ntry {\n var_dump(define(array(1,2,3,4,5), 1));\n} catch (TypeError $e) {\n echo \"TypeError: \", $e->getMessage(), \"\\n\";\n}\nvar_dump(define(\"TRUE\", 1));\nvar_dump(define(\" \", 1));\nvar_dump(define(\"[[[\", 2));\nvar_dump(define(\"test const\", 3));\nvar_dump(define(\"test const\", 3));\nvar_dump(define(\"test\", array(1)));\nvar_dump(define(\"test1\", fopen(__FILE__, 'r')));\nvar_dump(define(\"test2\", new stdclass));\nvar_dump(constant(\" \"));\nvar_dump(constant(\"[[[\"));\nvar_dump(constant(\"test const\"));\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-009.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/009.phpt
it("get_class() tests", function () {
expect(parser.parseCode("<?php\nclass foo {\n function bar () {\n var_dump(get_class());\n }\n function testNull ()\n {\n try {\n var_dump(get_class(null));\n } catch (TypeError $e) {\n echo $e->getMessage(), \"\\n\";\n }\n }\n}\nclass foo2 extends foo {\n}\n$f1 = new foo;\n$f2 = new foo2;\n$f1->bar();\n$f2->bar();\ntry {\n var_dump(get_class());\n} catch (Error $e) {\n echo $e->getMessage(), \"\\n\";\n}\ntry {\n var_dump(get_class(\"qwerty\"));\n} catch (TypeError $e) {\n echo $e->getMessage(), \"\\n\";\n}\nvar_dump(get_class($f1));\nvar_dump(get_class($f2));\n$f1->testNull();\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-010.test.js
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-011.test.js
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-012.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/012.phpt
it("class_exists() tests", function () {
expect(parser.parseCode("<?php\nclass foo {\n}\nvar_dump(class_exists(\"qwerty\"));\nvar_dump(class_exists(\"\"));\nvar_dump(class_exists(\"test\", false));\nvar_dump(class_exists(\"foo\", false));\nvar_dump(class_exists(\"foo\"));\nvar_dump(class_exists(\"stdClass\", false));\nvar_dump(class_exists(\"stdClass\"));\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-013.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/013.phpt
it("interface_exists() tests", function () {
expect(parser.parseCode("<?php\ninterface foo {\n}\nvar_dump(interface_exists(\"qwerty\"));\nvar_dump(interface_exists(\"\"));\nvar_dump(interface_exists(\"test\", false));\nvar_dump(interface_exists(\"foo\", false));\nvar_dump(interface_exists(\"foo\"));\nvar_dump(interface_exists(\"stdClass\", false));\nvar_dump(interface_exists(\"stdClass\"));\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-014.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/014.phpt
it("get_included_files() tests", function () {
expect(parser.parseCode("<?php\nvar_dump(get_included_files());\ninclude(__DIR__.\"/014.inc\");\nvar_dump(get_included_files());\ninclude_once(__DIR__.\"/014.inc\");\nvar_dump(get_included_files());\ninclude(__DIR__.\"/014.inc\");\nvar_dump(get_included_files());\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-015.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/015.phpt
it("trigger_error() tests", function () {
expect(parser.parseCode("<?php\nvar_dump(trigger_error(\"error\"));\ntry {\n var_dump(trigger_error(\"error\", -1));\n} catch (\\ValueError $e) {\n echo $e->getMessage() . \\PHP_EOL;\n}\ntry {\n var_dump(trigger_error(\"error\", 0));\n} catch (\\ValueError $e) {\n echo $e->getMessage() . \\PHP_EOL;\n}\nvar_dump(trigger_error(\"error\", E_USER_WARNING));\nvar_dump(trigger_error(\"error\", E_USER_DEPRECATED));\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-016.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/016.phpt
it("isset() with object properties when operating on non-object", function () {
expect(parser.parseCode("<?php\n$foo = NULL;\nisset($foo->bar->bar);\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-017.test.js
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-018.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/018.phpt
it("constant() tests", function () {
expect(parser.parseCode("<?php\ntry {\n var_dump(constant(\"\"));\n} catch (Error $e) {\n echo $e->getMessage(), \"\\n\";\n}\ndefine(\"TEST_CONST\", 1);\nvar_dump(constant(\"TEST_CONST\"));\ndefine(\"TEST_CONST2\", \"test\");\nvar_dump(constant(\"TEST_CONST2\"));\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-019.test.js
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-020.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/020.phpt
it("func_get_arg() invalid usage", function () {
expect(parser.parseCode("<?php\ntry {\n var_dump(func_get_arg(1));\n} catch (\\Error $e) {\n echo $e->getMessage() . \\PHP_EOL;\n}\nfunction bar() {\n var_dump(func_get_arg(1));\n}\nfunction foo() {\n bar(func_get_arg(1));\n}\ntry {\n foo(1,2);\n} catch (\\Error $e) {\n echo $e->getMessage() . \\PHP_EOL;\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-021.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/021.phpt
it("?: operator", function () {
expect(parser.parseCode("<?php\nvar_dump(true ?: false);\nvar_dump(false ?: true);\nvar_dump(23 ?: 42);\nvar_dump(0 ?: \"bar\");\n$a = 23;\n$b = 0;\n$c = \"\";\n$d = 23.5;\nvar_dump($a ?: $b);\nvar_dump($c ?: $d);\nvar_dump(1 ?: print(2));\n$e = array();\n$e['e'] = 'e';\n$e['e'] = $e['e'] ?: 'e';\nprint_r($e);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-022.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/022.phpt
it("Implementing abstracting methods and optional parameters", function () {
expect(parser.parseCode("<?php\nabstract class Base\n{\n abstract function someMethod($param);\n}\nclass Ext extends Base\n{\n function someMethod($param = \"default\")\n {\n echo $param, \"\\n\";\n }\n}\n$a = new Ext();\n$a->someMethod(\"foo\");\n$a->someMethod();\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-023.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/023.phpt
it("Testing variable variables as function name", function () {
expect(parser.parseCode("<?php\n$a = 'ucfirst';\n$b = 'a';\nprint $$b('test');\nprint \"\\n\";\nclass bar {\n public function a() {\n return \"bar!\";\n }\n}\nclass foo {\n public function test() {\n print \"foo!\\n\";\n return new bar;\n }\n}\nfunction test() {\n return new foo;\n}\n$a = 'test';\n$b = 'a';\nvar_dump($$b()->$$b()->$b());\n$a = 'strtoupper';\n$b = 'a';\n$c = 'b';\n$d = 'c';\nvar_dump($$$$d('foo'));\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-024.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/024.phpt
it("Testing operations with undefined variable", function () {
expect(parser.parseCode("<?php\nvar_dump($a[1]);\nvar_dump($a[$c]);\nvar_dump($a + 1);\nvar_dump($a + $b);\nvar_dump($a++);\nvar_dump(++$b);\nvar_dump($a->$b);\nvar_dump($a->$b);\nvar_dump($a->$b->{$c[1]});\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-025.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/025.phpt
it("Testing dynamic calls", function () {
expect(parser.parseCode("<?php\nclass foo {\n static public function a() {\n print \"ok\\n\";\n }\n}\n$a = 'a';\n$b = 'a';\n$class = 'foo';\nfoo::a();\nfoo::$a();\nfoo::$$b();\n$class::a();\n$class::$a();\n$class::$$b();\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-026.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/026.phpt
it("Trying assign value to property when an object is not returned in a function", function () {
expect(parser.parseCode("<?php\nclass foo {\n public function a() {\n }\n}\n$test = new foo;\n$test->a()->a;\nprint \"ok\\n\";\ntry {\n $test->a()->a = 1;\n} catch (Error $e) {\n echo $e->getMessage(), \"\\n\";\n}\nprint \"ok\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-027.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/027.phpt
it("Testing dynamic calls using variable variables with curly syntax", function () {
expect(parser.parseCode("<?php\n$a = 'b';\n$b = 'c';\n$c = 'strtoupper';\nvar_dump(${${$a}}('foo') == 'FOO');\n$a = 'b';\n$b = 'c';\n$c = 'strtoupper';\n$strtoupper = 'strtolower';\nvar_dump(${${++$a}}('FOO') == 'foo');\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-028.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/028.phpt
it("Testing function call through of array item", function () {
expect(parser.parseCode("<?php\n$arr = array('strtoupper', 'strtolower');\n$k = 0;\nvar_dump($arr[0]('foo') == 'FOO');\nvar_dump($arr[$k]('foo') == 'FOO');\nvar_dump($arr[++$k]('FOO') == 'foo');\nvar_dump($arr[++$k]('FOO') == 'foo');\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-029.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/029.phpt
it("Testing assign to property of an object in an array", function () {
expect(parser.parseCode("<?php\n$arr = array(new stdClass);\n$arr[0]->a = clone $arr[0];\nvar_dump($arr);\n$arr[0]->b = new $arr[0];\nvar_dump($arr);\n$arr[0]->c = $arr[0]->a;\nvar_dump($arr);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-030.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/030.phpt
it("Overriding $this in catch and checking the object properties later.", function () {
expect(parser.parseCode("<?php\nclass foo {\n public $test = 0;\n private $test_2 = 1;\n protected $test_3 = 2;\n public function bar() {\n try {\n throw new Exception('foo');\n } catch (Exception $this) {\n var_dump($this);\n }\n $this->baz();\n }\n public function baz() {\n foreach ($this as $k => $v) {\n printf(\"'%s' => '%s'\\n\", $k, $v);\n }\n print \"ok\\n\";\n }\n}\n$test = new foo;\n$test->bar();\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-031.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/031.phpt
it("Testing array with '[]' passed as argument by value", function () {
expect(parser.parseCode("<?php\nfunction test($var) { }\ntest($arr[]);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-032.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/032.phpt
it("Testing array with '[]' passed as argument by reference", function () {
expect(parser.parseCode("<?php\nfunction test(&$var) { }\ntest($arr[]);\nprint \"ok!\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-033.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/033.phpt
it("Using undefined multidimensional array", function () {
expect(parser.parseCode("<?php\n$arr[1][2][3][4][5];\necho $arr[1][2][3][4][5];\n$arr[1][2][3][4][5]->foo;\ntry {\n $arr[1][2][3][4][5]->foo = 1;\n} catch (Error $e) {\n echo $e->getMessage(), \"\\n\";\n}\n$arr[][] = 2;\ntry {\n $arr[][]->bar = 2;\n} catch (Error $e) {\n echo $e->getMessage(), \"\\n\";\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-034.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/034.phpt
it("Testing multiples 'default:' in switch", function () {
expect(parser.parseCode("<?php\nswitch (1) {\n case 2:\n print 'foo';\n break;\n case 3:\n print 'bar';\n break;\n default:\n print 1;\n break;\n default:\n print 2;\n break;\n default:\n print 3;\n break;\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-035.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/035.phpt
it("Using 'static' and 'global' in global scope", function () {
expect(parser.parseCode("<?php\nstatic $var, $var, $var = -1;\nvar_dump($var);\nglobal $var, $var, $var;\nvar_dump($var);\nvar_dump($GLOBALS['var']);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-036.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/036.phpt
it("Trying to use lambda in array offset", function () {
expect(parser.parseCode("<?php\ntry {\n $test[function(){}] = 1;\n} catch (Error $e) {\n echo $e->getMessage(), \"\\n\";\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-037.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/037.phpt
it("Trying to access inexistent static property of Closure", function () {
expect(parser.parseCode("<?php\nnamespace closure;\nclass closure { static $x = 1;}\n$x = __NAMESPACE__;\nvar_dump(closure::$x);\nvar_dump($x::$x);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-038.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/038.phpt
it("Trying to use lambda as array key", function () {
expect(parser.parseCode("<?php\ntry {\n var_dump(array(function() { } => 1));\n} catch (Error $e) {\n echo $e->getMessage(), \"\\n\";\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-67468.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/67468.phpt
it("Bug #67468 (Segfault in highlight_file()/highlight_string())", function () {
expect(parser.parseCode("<?php\nhighlight_string(\"<?php __CLASS__;\", true);\necho \"done\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-ArrayAccess_indirect_append.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/ArrayAccess_indirect_append.phpt
it("Using indirect append on ArrayAccess object", function () {
expect(parser.parseCode("<?php\nclass AA implements ArrayAccess {\n private $data = [];\n public function &offsetGet($name): mixed {\n if (null === $name) {\n return $this->data[];\n } else {\n return $this->data[$name];\n }\n }\n public function offsetSet($name, $value): void {\n $this->data[$name] = $value;\n }\n public function offsetUnset($name): void {}\n public function offsetExists($name): bool {}\n}\n$aa = new AA;\n$aa[3] = 1;\n$aa[][][0] = 2;\nvar_dump($aa);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-ErrorException_construct.test.js
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-ErrorException_getSeverity.test.js

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-abstract-static.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/abstract-static.phpt
it("Test for abstract static classes", function () {
expect(parser.parseCode("<?php\nabstract class TestClass\n{\n abstract static public function getName();\n}\n?>\n===DONE===")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-abstract_inheritance_001.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/abstract_inheritance_001.phpt
it("Allow abstract function override", function () {
expect(parser.parseCode("<?php\nabstract class A { abstract function bar($x); }\nabstract class B extends A { abstract function bar($x); }\necho \"DONE\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-abstract_inheritance_002.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/abstract_inheritance_002.phpt
it("Allow abstract function override", function () {
expect(parser.parseCode("<?php\nabstract class A { abstract function bar($x); }\nabstract class B extends A { abstract function bar($x, $y = 0); }\necho \"DONE\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-abstract_inheritance_003.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/abstract_inheritance_003.phpt
it("Allow abstract function override", function () {
expect(parser.parseCode("<?php\nabstract class A { abstract function bar($x, $y = 0); }\nabstract class B extends A { abstract function bar($x); }\necho \"DONE\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-access_modifiers_001.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/access_modifiers_001.phpt
it("using multiple access modifiers (methods)", function () {
expect(parser.parseCode("<?php\nclass test {\n static public public static final public final function foo() {\n }\n}\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-access_modifiers_002.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/access_modifiers_002.phpt
it("using multiple access modifiers (attributes)", function () {
expect(parser.parseCode("<?php\nclass test {\n static public public static final public final $var;\n}\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-access_modifiers_003.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/access_modifiers_003.phpt
it("using multiple access modifiers (classes)", function () {
expect(parser.parseCode("<?php\nfinal final class test {\n function foo() {}\n}\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-access_modifiers_004.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/access_modifiers_004.phpt
it("using multiple access modifiers (abstract methods)", function () {
expect(parser.parseCode("<?php\nclass test {\n abstract abstract function foo() {\n }\n}\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-access_modifiers_005.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/access_modifiers_005.phpt
it("using multiple access modifiers (final methods)", function () {
expect(parser.parseCode("<?php\nclass test {\n final final function foo() {\n }\n}\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-access_modifiers_006.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/access_modifiers_006.phpt
it("using multiple access modifiers (static methods)", function () {
expect(parser.parseCode("<?php\nclass test {\n static static function foo() {\n }\n}\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-access_modifiers_007.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/access_modifiers_007.phpt
it("abstract final methods errmsg", function () {
expect(parser.parseCode("<?php\nclass test {\n final abstract function foo();\n}\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-access_modifiers_008.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/access_modifiers_008.phpt
it("Inconsistencies when accessing protected members", function () {
expect(parser.parseCode("<?php\nclass A {\n static protected function f() {return 'A::f()';}\n}\nclass B1 extends A {\n static protected function f() {return 'B1::f()';}\n}\nclass B2 extends A {\n static public function test() {echo B1::f();}\n}\nB2::test();\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-access_modifiers_009.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/access_modifiers_009.phpt
it("Inconsistencies when accessing protected members - 2", function () {
expect(parser.parseCode("<?php\nclass A {\n static protected function f() {return 'A::f()';}\n}\nclass B1 extends A {\n static protected function f() {return 'B1::f()';}\n}\nclass B2 extends A {\n static public function test() {\n var_dump(is_callable('B1::f'));\n B1::f();\n }\n}\nB2::test();\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-access_modifiers_010.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/access_modifiers_010.phpt
it("Testing visibility of methods", function () {
expect(parser.parseCode("<?php\nclass d {\n private function test2() {\n print \"Bar\\n\";\n }\n}\nabstract class a extends d {\n public function test() {\n $this->test2();\n }\n}\nabstract class b extends a {\n}\nclass c extends b {\n public function __construct() {\n $this->test();\n }\n}\nnew c;\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-access_modifiers_011.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/access_modifiers_011.phpt
it("__call() for private/protected methods", function () {
expect(parser.parseCode("<?php\nclass A {\n private $var1 = 'var1 value';\n protected $var2 = 'var2 value';\n private function func1()\n {\n return \"in func1\";\n }\n protected function func2()\n {\n return \"in func2\";\n }\n public function __get($var)\n {\n return $this->$var;\n }\n public function __call($func, array $args = array())\n {\n return call_user_func_array(array($this, $func), $args);\n }\n}\n$a = new A();\necho $a->var1,\"\\n\";\necho $a->var2,\"\\n\";\necho $a->func1(),\"\\n\";\necho $a->func2(),\"\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-access_modifiers_012.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/access_modifiers_012.phpt
it("Trigger __call() in lieu of non visible methods when called via a callback.", function () {
expect(parser.parseCode("<?php\nclass C {\n protected function prot() { }\n private function priv() { }\n public function __call($name, $args) {\n echo \"In __call() for method $name()\\n\";\n }\n}\n$c = new C;\ncall_user_func(array($c, 'none'));\ncall_user_func(array($c, 'prot'));\ncall_user_func(array($c, 'priv'));\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-access_modifiers_013.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/access_modifiers_013.phpt
it("Prevent abstract and final in the same class declaration", function () {
expect(parser.parseCode("<?php\nfinal abstract class C {\n private function priv() { }\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-add_001.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/add_001.phpt
it("adding arrays", function () {
expect(parser.parseCode("<?php\n$a = array(1,2,3);\n$b = array(\"str\", \"here\");\n$c = $a + $b;\nvar_dump($c);\n$a = array(1,2,3);\n$b = array(1,2,4);\n$c = $a + $b;\nvar_dump($c);\n$a = array(\"a\"=>\"aaa\",2,3);\n$b = array(1,2,\"a\"=>\"bbbbbb\");\n$c = $a + $b;\nvar_dump($c);\n$a += $b;\nvar_dump($c);\n$a += $a;\nvar_dump($c);\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-add_002.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/add_002.phpt
it("adding objects to arrays", function () {
expect(parser.parseCode("<?php\n$a = array(1,2,3);\n$o = new stdclass;\n$o->prop = \"value\";\ntry {\n var_dump($a + $o);\n} catch (Error $e) {\n echo \"\\nException: \" . $e->getMessage() . \"\\n\";\n}\n$c = $a + $o;\nvar_dump($c);\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-add_003.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/add_003.phpt
it("adding arrays to objects", function () {
expect(parser.parseCode("<?php\n$a = array(1,2,3);\n$o = new stdclass;\n$o->prop = \"value\";\ntry {\n var_dump($o + $a);\n} catch (Error $e) {\n echo \"\\nException: \" . $e->getMessage() . \"\\n\";\n}\n$c = $o + $a;\nvar_dump($c);\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-add_004.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/add_004.phpt
it("adding numbers to arrays", function () {
expect(parser.parseCode("<?php\n$a = array(1,2,3);\ntry {\n var_dump($a + 5);\n} catch (Error $e) {\n echo \"\\nException: \" . $e->getMessage() . \"\\n\";\n}\n$c = $a + 5;\nvar_dump($c);\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-add_005.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/add_005.phpt
it("adding integers to doubles", function () {
expect(parser.parseCode("<?php\n$i = 75636;\n$d = 2834681123.123123;\n$c = $i + $d;\nvar_dump($c);\n$c = $d + $i;\nvar_dump($c);\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-add_006.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/add_006.phpt
it("adding numbers to strings", function () {
expect(parser.parseCode("<?php\n$i = 75636;\n$s1 = \"this is a string\";\n$s2 = \"876222numeric\";\n$s3 = \"48474874\";\n$s4 = \"25.68\";\ntry {\n $c = $i + $s1;\n var_dump($c);\n} catch (\\TypeError $e) {\n echo $e->getMessage() . \\PHP_EOL;\n}\n$c = $i + $s2;\nvar_dump($c);\n$c = $i + $s3;\nvar_dump($c);\n$c = $i + $s4;\nvar_dump($c);\ntry {\n $c = $s1 + $i;\n var_dump($c);\n} catch (\\TypeError $e) {\n echo $e->getMessage() . \\PHP_EOL;\n}\n$c = $s2 + $i;\nvar_dump($c);\n$c = $s3 + $i;\nvar_dump($c);\n$c = $s4 + $i;\nvar_dump($c);\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-add_007.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/add_007.phpt
it("adding strings to arrays", function () {
expect(parser.parseCode("<?php\n$a = array(1,2,3);\n$s1 = \"some string\";\ntry {\n var_dump($a + $s1);\n} catch (Error $e) {\n echo \"\\nException: \" . $e->getMessage() . \"\\n\";\n}\n$c = $a + $s1;\nvar_dump($c);\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-add_optional_by_ref_arg.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/add_optional_by_ref_arg.phpt
it("Adding an optional by-ref arg in a child method", function () {
expect(parser.parseCode("<?php\nclass Test1 {\n public function method1() {\n $this->method2($x);\n var_dump($x);\n }\n public function method2() {}\n}\nclass Test2 extends Test1 {\n public function method2(&$x = null) {\n ++$x;\n }\n}\n(new Test2)->method1();\n?>")).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/alternative_offset_syntax_compile_error_in_const_expr.phpt
it("Alternative offset syntax should emit E_COMPILE_ERROR in const expression", function () {
expect(parser.parseCode("<?php\nconst FOO_COMPILE_ERROR = \"BAR\"{0};\nvar_dump(FOO_COMPILE_ERROR);\n?>")).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/alternative_offset_syntax_compile_error_outside_const_expr.phpt
it("Alternative offset syntax should emit E_COMPILE_ERROR outside const expression", function () {
expect(parser.parseCode("<?php\n$foo = 'BAR';\nvar_dump($foo{0});\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-and_001.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/and_001.phpt
it("bitwise AND and strings", function () {
expect(parser.parseCode("<?php\n$s = \"123\";\n$s1 = \"234\";\nvar_dump($s & $s1);\n$s = \"test\";\n$s1 = \"some\";\nvar_dump($s & $s1);\n$s = \"test long\";\n$s1 = \"some\";\nvar_dump($s & $s1);\n$s = \"test\";\n$s1 = \"some long\";\nvar_dump($s & $s1);\n$s = \"test\";\n$s &= \"some long\";\nvar_dump($s);\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-anon-001.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/anon/001.phpt
it("declare bare anonymous class", function () {
expect(parser.parseCode("<?php\nvar_dump(new class{});\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-anon-002.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/anon/002.phpt
it("declare anonymous class extending another", function () {
expect(parser.parseCode("<?php\nclass A{}\ninterface B{\n public function method();\n}\n$a = new class extends A implements B {\n public function method(){\n return true;\n }\n};\nvar_dump($a instanceof A, $a instanceof B);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-anon-003.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/anon/003.phpt
it("reusing anonymous classes", function () {
expect(parser.parseCode("<?php\nwhile (@$i++<10) {\n var_dump(new class($i) {\n public function __construct($i) {\n $this->i = $i;\n }\n });\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-anon-004.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/anon/004.phpt
it("testing anonymous inheritance", function () {
expect(parser.parseCode("<?php\nclass Outer {\n protected $data;\n public function __construct($data) {\n $this->data = $data;\n }\n public function getArrayAccess() {\n /* create a proxy object implementing array access */\n return new class($this->data) extends Outer implements ArrayAccess {\n public function offsetGet($offset): mixed { return $this->data[$offset]; }\n public function offsetSet($offset, $data): void { $this->data[$offset] = $data; }\n public function offsetUnset($offset): void { unset($this->data[$offset]); }\n public function offsetExists($offset): bool { return isset($this->data[$offset]); }\n };\n }\n}\n$outer = new Outer(array(\n rand(1, 100)\n));\n/* not null because inheritance */\nvar_dump($outer->getArrayAccess()[0]);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-anon-005.test.js
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-anon-006.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/anon/006.phpt
it("testing anon classes inside namespaces", function () {
expect(parser.parseCode("<?php\nnamespace lone {\n $hello = new class{} ;\n}\nnamespace {\n var_dump ($hello);\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-anon-007.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/anon/007.phpt
it("testing anon classes in functions outside of classes in namespaces", function () {
expect(parser.parseCode("<?php\nnamespace lone {\n function my_factory() {\n return new class{};\n }\n class Outer {\n public function __construct() {\n var_dump(\n my_factory());\n }\n }\n new Outer();\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-anon-008.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/anon/008.phpt
it("testing static access for methods and properties in anon classes", function () {
expect(parser.parseCode("<?php\n$anonClass = new class(\"cats\", \"dogs\") {\n public static $foo;\n private static $bar;\n public function __construct($foo, $bar) {\n static::$foo = $foo;\n static::$bar = $bar;\n }\n public static function getBar() {\n return static::$bar;\n }\n};\nvar_dump($anonClass::$foo);\nvar_dump($anonClass::getBar());\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-anon-009.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/anon/009.phpt
it("testing traits in anon classes", function () {
expect(parser.parseCode("<?php\ntrait Foo {\n public function someMethod() {\n return \"bar\";\n }\n}\n$anonClass = new class {\n use Foo;\n};\nvar_dump($anonClass->someMethod());\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-anon-010.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/anon/010.phpt
it("Trait binding after anon class", function () {
expect(parser.parseCode("<?php\ntrait T {\n public function m1() { return 42; }\n}\nclass C {\n public function m2() {\n return new class {};\n }\n use T;\n}\n$c = new C;\nvar_dump($c->m1());\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-anon-011.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/anon/011.phpt
it("Ensure proper inheritance with get_class(anon class instance) used via class_alias (see also bug #70106)", function () {
expect(parser.parseCode("<?php\nclass_alias(get_class(new class { protected $foo = 1; }), \"AnonBase\");\nvar_dump((new class extends AnonBase {\n function getFoo() {\n return $this->foo;\n }\n})->getFoo());\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-anon-012.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/anon/012.phpt
it("Ensure correct unmangling of private property names for anonymous class instances", function () {
expect(parser.parseCode("<?php\nvar_dump(new class { private $foo; });\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-anon-013.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/anon/013.phpt
it("closure binding to anonymous class", function () {
expect(parser.parseCode("<?php\n$class = new class {};\n$foo = function() {\n return $this;\n};\n$closure = Closure::bind($foo, $class, $class);\nvar_dump($closure());\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-anon-014.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/anon/014.phpt
it("anonymous class trait binding", function () {
expect(parser.parseCode("<?php\ntrait TaskTrait {\n function run() {\n return 'Running...';\n }\n}\n$class = new class() {\n use TaskTrait;\n};\nvar_dump($class->run());\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-anon-015.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/anon/015.phpt
it("static variables in methods inherited from parent class", function () {
expect(parser.parseCode("<?php\nclass C {\n function foo ($y = null) {\n static $x = null;\n if (!is_null($y)) {\n $x = [$y];\n }\n return $x;\n }\n}\n$c = new C();\n$c->foo(42);\n$d = new class extends C {};\nvar_dump($d->foo());\nvar_dump($d->foo(24));\nvar_dump($c->foo());\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-anon-016.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/anon/016.phpt
it("static variables in methods inherited from parent class (can't cache objects)", function () {
expect(parser.parseCode("<?php\nclass C {\n function foo ($y = null) {\n static $x = null;\n if (!is_null($y)) {\n $x = [$y];\n }\n return $x;\n }\n}\n$c = new C();\n$c->foo(new stdClass);\n$d = new class extends C {};\nvar_dump($d->foo());\nvar_dump($d->foo(24));\nvar_dump($c->foo());\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-anon_class_name.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/anon_class_name.phpt
it("Generated names for anonymous classes", function () {
expect(parser.parseCode("<?php\nnamespace DeclaringNS {\n class Test1 {}\n interface Test2 {}\n interface Test3 {}\n}\nnamespace UsingNS {\n function print_name(object $obj) {\n echo strstr(get_class($obj), \"\\0\", true), \"\\n\";\n }\n print_name(new class {});\n print_name(new class extends \\DeclaringNS\\Test1 {});\n print_name(new class extends \\DeclaringNS\\Test1 implements \\DeclaringNS\\Test2 {});\n print_name(new class implements \\DeclaringNS\\Test2 {});\n print_name(new class implements \\DeclaringNS\\Test2, \\DeclaringNS\\Test3 {});\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-arg_unpack-basic.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/arg_unpack/basic.phpt
it("Basic argument unpacking", function () {
expect(parser.parseCode("<?php\nfunction test(...$args) {\n var_dump($args);\n}\nfunction test2($arg1, $arg2, $arg3 = null) {\n var_dump($arg1, $arg2, $arg3);\n}\nfunction getArray($array) {\n return $array;\n}\nfunction arrayGen($array) {\n foreach ($array as $element) {\n yield $element;\n }\n}\n$array = [1, 2, 3];\ntest(...[]);\ntest(...[1, 2, 3]);\ntest(...$array);\ntest(...getArray([1, 2, 3]));\ntest(...arrayGen([]));\ntest(...arrayGen([1, 2, 3]));\ntest(1, ...[2, 3], ...[4, 5]);\ntest(1, ...getArray([2, 3]), ...arrayGen([4, 5]));\ntest2(...[1, 2]);\ntest2(...[1, 2, 3]);\ntest2(...[1], ...[], ...[], ...[2, 3], ...[4, 5]);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-arg_unpack-by_ref.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/arg_unpack/by_ref.phpt
it("Argument unpacking with by-ref arguments", function () {
expect(parser.parseCode("<?php\nerror_reporting(E_ALL);\nfunction test1(&...$args) {\n foreach ($args as &$arg) {\n $arg++;\n }\n}\ntest1(...[1, 2, 3]);\n$array = [1, 2, 3];\ntest1(...$array);\nvar_dump($array);\n$array1 = [1, 2]; $array2 = [3, 4];\ntest1(...$array1, ...$array2);\nvar_dump($array1, $array2);\nfunction test2($val1, &$ref1, $val2, &$ref2) {\n $ref1++;\n $ref2++;\n}\n$array = [0, 0, 0, 0];\ntest2(...$array);\nvar_dump($array);\n$array1 = [1, 2]; $array2 = [4, 5];\ntest1(...$array1, ...$array2);\nvar_dump($array1, $array2);\n$a = $b = $c = $d = 0;\n$array = [0, 0, 0, 0];\ntest2($a, ...$array);\nvar_dump($a, $array);\ntest2($a, $b, ...$array);\nvar_dump($a, $b, $array);\ntest2($a, $b, $c, ...$array);\nvar_dump($a, $b, $c, $array);\ntest2($a, $b, $c, $d, ...$array);\nvar_dump($a, $b, $c, $d, $array);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-arg_unpack-by_ref_separation.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/arg_unpack/by_ref_separation.phpt
it("Array must be separated if unpacking by reference", function () {
expect(parser.parseCode("<?php\nfunction inc(&... $args) {\n foreach ($args as &$arg) {\n $arg++;\n }\n}\n$arr = [1, 2];\n$arr[] = 3;\n$arr2 = $arr;\ninc(...$arr);\nvar_dump($arr);\nvar_dump($arr2);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-arg_unpack-dynamic.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/arg_unpack/dynamic.phpt
it("Unpack arguments for dynamic call", function () {
expect(parser.parseCode("<?php\n$fn = function(...$args) {\n var_dump($args);\n};\n$fn(...[]);\n$fn(...[1, 2, 3]);\n$fn(1, ...[2, 3], ...[], ...[4, 5]);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-arg_unpack-internal.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/arg_unpack/internal.phpt
it("Argument unpacking with internal functions", function () {
expect(parser.parseCode("<?php\n$arrays = [\n [1, 2, 3],\n [4, 5, 6],\n [7, 8, 9],\n];\nvar_dump(array_map(null, ...$arrays));\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-arg_unpack-invalid_type.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/arg_unpack/invalid_type.phpt
it("Only arrays and Traversables can be unpacked", function () {
expect(parser.parseCode("<?php\nfunction test(...$args) {\n var_dump($args);\n}\ntry {\n test(...null);\n} catch (Error $e) {\n echo $e->getMessage(), \"\\n\";\n}\ntry {\n test(...42);\n} catch (Error $e) {\n echo $e->getMessage(), \"\\n\";\n}\ntry {\n test(...new stdClass);\n} catch (Error $e) {\n echo $e->getMessage(), \"\\n\";\n}\ntry {\n test(1, 2, 3, ...\"foo\", ...[4, 5]);\n} catch (Error $e) {\n echo $e->getMessage(), \"\\n\";\n}\ntry {\n test(1, 2, 3, ...new StdClass, ...3.14, ...[4, 5]);\n} catch (Error $e) {\n echo $e->getMessage(), \"\\n\";\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-arg_unpack-many_args.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/arg_unpack/many_args.phpt
it("Argument unpacking with many arguments", function () {
expect(parser.parseCode("<?php\nfunction f(...$args) {\n var_dump(count($args));\n}\n$array = array_fill(0, 10000, 42);\nf(...$array, ...$array);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-arg_unpack-method.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/arg_unpack/method.phpt
it("Unpack arguments for method calls", function () {
expect(parser.parseCode("<?php\nclass Foo {\n public function test(...$args) {\n var_dump($args);\n }\n public static function test2(...$args) {\n var_dump($args);\n }\n}\n$foo = new Foo;\nFoo::test2(1, 2, ...[3, 4], ...[], ...[5]);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-arg_unpack-new.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/arg_unpack/new.phpt
it("Unpack arguments for new expression", function () {
expect(parser.parseCode("<?php\nclass Foo {\n public function __construct(...$args) {\n var_dump($args);\n }\n}\nnew Foo(...[]);\nnew Foo(...[1, 2, 3]);\nnew Foo(...[1], ...[], ...[2, 3]);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-arg_unpack-non_integer_keys.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/arg_unpack/non_integer_keys.phpt
it("Argument unpacking does not work with non-integer keys", function () {
expect(parser.parseCode("<?php\nfunction foo(...$args) {\n var_dump($args);\n}\nfunction gen() {\n yield 1.23 => 123;\n yield \"2.34\" => 234;\n}\ntry {\n foo(...gen());\n} catch (Error $ex) {\n echo \"Exception: \" . $ex->getMessage() . \"\\n\";\n}\n?>")).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/arg_unpack/positional_arg_after_unpack_error.phpt
it("Positional arguments cannot be used after argument unpacking", function () {
expect(parser.parseCode("<?php\nvar_dump(...[1, 2, 3], 4);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-arg_unpack-string_keys.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/arg_unpack/string_keys.phpt
it("Argument unpacking does not work with string keys (forward compatibility for named args)", function () {
expect(parser.parseCode("<?php\nset_error_handler(function($errno, $errstr) {\n var_dump($errstr);\n});\ntry {\n var_dump(...new ArrayIterator([1, 2, \"foo\" => 3, 4]));\n} catch (Error $ex) {\n var_dump($ex->getMessage());\n}\n?>")).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/arg_unpack/traversable_throwing_exception.phpt
it("Traversables that throw exceptions are properly handled during argument unpack", function () {
expect(parser.parseCode("<?php\nfunction test(...$args) {\n var_dump($args);\n}\nclass Foo implements IteratorAggregate {\n public function getIterator(): Traversable {\n throw new Exception('getIterator');\n }\n}\nfunction gen() {\n yield 1;\n yield 2;\n throw new Exception('gen');\n}\ntry {\n test(1, 2, ...new Foo, ...[3, 4]);\n} catch (Exception $e) { var_dump($e->getMessage()); }\ntry {\n test(1, 2, ...gen(), ...[3, 4]);\n} catch (Exception $e) { var_dump($e->getMessage()); }\n?>")).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/arg_unpack/traversable_with_by_ref_parameters.phpt
it("Traversables cannot be unpacked into by-reference parameters", function () {
expect(parser.parseCode("<?php\nfunction test($val1, $val2, $val3, &$ref) {\n $ref = 42;\n}\nfunction gen($array) {\n foreach ($array as $element) {\n yield $element;\n }\n}\ntest(1, 2, 3, $b, ...gen([4, 5, 6]));\nvar_dump($b);\ntest(...gen([1, 2, 3, 4]));\ntest(1, 2, ...gen([3, 4]));\ntest(...gen([1, 2]), ...gen([3, 4]));\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-arginfo_zpp_mismatch.test.js
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-arginfo_zpp_mismatch_strict.test.js
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-argument_restriction_001.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/argument_restriction_001.phpt
it("Bug #55719 (Argument restriction should come with a more specific error message)", function () {
expect(parser.parseCode("<?php\nClass Base {\n public function &test($foo, array $bar, $option = NULL, $extra = \"lllllllllllllllllllllllllllllllllllllllllllllllllll\") {\n }\n}\nclass Sub extends Base {\n public function &test() {\n }\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-argument_restriction_002.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/argument_restriction_002.phpt
it("Bug #55719 (Argument restriction should come with a more specific error message)", function () {
expect(parser.parseCode("<?php\nAbstract Class Base {\n public function test($foo, array &$bar, $option = NULL, $extra = 3.141592653589793238462643383279502884197169399375105 ) {\n }\n}\nclass Sub extends Base {\n public function test($foo, array &$bar) {\n }\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-argument_restriction_003.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/argument_restriction_003.phpt
it("Bug #55719 (Argument restriction should come with a more specific error message)", function () {
expect(parser.parseCode("<?php\nclass Foo {\n}\nAbstract Class Base {\n public function test(Foo $foo, array $bar, $option = NULL, $extra = \"lllllllllllllllllllllllllllllllllllllllllllllllllll\") {\n }\n}\nclass Sub extends Base {\n public function test() {\n }\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-argument_restriction_004.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/argument_restriction_004.phpt
it("Bug #55719 (Argument restriction should come with a more specific error message)", function () {
expect(parser.parseCode("<?php\nclass Foo {\n}\nAbstract Class Base {\n abstract public function test(Foo $foo, array $bar, $option = NULL, $extra = 16777215) ;\n}\nclass Sub extends Base {\n public function test(Foo $foo, array $bar, $option = NULL, $extra = 0xffffff ) {\n }\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-argument_restriction_005.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/argument_restriction_005.phpt
it("Bug #55719 (Argument restriction should come with a more specific error message)", function () {
expect(parser.parseCode("<?php\nclass Sub implements ArrayAccess {\n public function offsetSet(): void {\n }\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-argument_restriction_006.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/argument_restriction_006.phpt
it("Bug #60174 (Notice when array in method prototype error)", function () {
expect(parser.parseCode("<?php\nAbstract Class Base {\n public function test($foo, $extra = array(\"test\")) {\n }\n}\nclass Sub extends Base {\n public function test($foo, $extra) {\n }\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-array_add_indirect.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_add_indirect.phpt
it("Array addition should not add INDIRECT elements", function () {
expect(parser.parseCode("<?php\n$x = 1;\n$ary = ['y' => 1];\n$ary += $GLOBALS;\nvar_dump($ary['x']);\n$x = 2;\nvar_dump($ary['x']);\n?>")).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_addition_not_commutative.phpt
it("Array addition is not commutative -- do not swap operands", function () {
expect(parser.parseCode("<?php\n$array = [1, 2, 3];\n$array = [4, 5, 6] + $array;\nvar_dump($array);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-array_append_COW.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_append_COW.phpt
it("Tests that array manipulation code is correctly dealing with copy on write and splitting on reference", function () {
expect(parser.parseCode("<?php\n $a=array();\n $b=1;\n $c=&$b;\n $a[]=$b;\n $b=2;\n var_dump ($a);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-array_hash_zero.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_hash_zero.phpt
it("Accept hashes being equal to zero", function () {
expect(parser.parseCode("<?php\n$hashes = [\n \"\\x8e\\x1a\\x63\\x0f\\x61\" => 32,\n \"\\xf7\\x17\\x7f\\x7f\\x7f\\x7f\\x7f\\x7f\\x7f\\x6b\\x03\\x6a\\x13\\x63\\x17\\x6b\\x1d\\x67\" => 64,\n];\nforeach ($hashes as $hash => $bits) {\n var_dump($hashes[$hash], $bits);\n}\n?>")).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_literal_next_element_error.phpt
it("Next free element may overflow in array literals", function () {
expect(parser.parseCode("<?php\n$i = PHP_INT_MAX;\ntry {\n $array = [$i => 42, new stdClass];\n var_dump($array);\n} catch (Error $e) {\n echo $e->getMessage(), \"\\n\";\n}\nfunction test($x = [PHP_INT_MAX => 42, \"foo\"]) {}\ntry {\n test();\n} catch (Error $e) {\n echo $e->getMessage(), \"\\n\";\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-array_offset.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_offset.phpt
it("Ensure \"undefined offset\" notice formats message correctly when undefined key is negative", function () {
expect(parser.parseCode("<?php\n[][-1];\n[][-1.1];\n(new ArrayObject)[-1];\n(new ArrayObject)[-1.1];\necho \"Done\\n\";\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-array_offset_002.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_offset_002.phpt
it("Capturing array in user error handler during index conversion", function () {
expect(parser.parseCode("<?php\nset_error_handler(function($code, $msg) {\n echo \"Err: $msg\\n\";\n $GLOBALS[''] = $GLOBALS['y'];\n});\nfunction x(&$s){\n $s[100000000000000000000] = 1;\n}\nx($y);\nvar_dump($y);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-array_self_add_globals.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_self_add_globals.phpt
it("Add $GLOBALS to itself", function () {
expect(parser.parseCode("<?php\n$x = $GLOBALS + $GLOBALS;\n?>\n===DONE===")).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_splice_empty_ht_iter_removal.phpt
it("HT iterator should be destroyed if array becomes empty during array_splice", function () {
expect(parser.parseCode("<?php\n$a=[4];\n$i = 0;\nforeach ($a as &$r) {\n var_dump($r);\n $a = array_splice($a, 0);\n if (++$i == 2) break;\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-array_unpack-already_occupied.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_unpack/already_occupied.phpt
it("Appending to an array via unpack may fail", function () {
expect(parser.parseCode("<?php\n$arr = [1, 2, 3];\ntry {\n var_dump([PHP_INT_MAX-1 => 0, ...$arr]);\n} catch (Error $e) {\n echo $e->getMessage(), \"\\n\";\n}\ntry {\n var_dump([PHP_INT_MAX-1 => 0, ...[1, 2, 3]]);\n} catch (Error $e) {\n echo $e->getMessage(), \"\\n\";\n}\nconst ARR = [1, 2, 3];\nfunction test($x = [PHP_INT_MAX-1 => 0, ...ARR]) {}\ntry {\n test();\n} catch (Error $e) {\n echo $e->getMessage(), \"\\n\";\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-array_unpack-basic.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_unpack/basic.phpt
it("Basic array unpacking", function () {
expect(parser.parseCode("<?php\n$array = [1, 2, 3];\nfunction getArr() {\n return [4, 5];\n}\nfunction arrGen() {\n for($i = 11; $i < 15; $i++) {\n yield $i;\n }\n}\nvar_dump([...[]]);\nvar_dump([...[1, 2, 3]]);\nvar_dump([...$array]);\nvar_dump([...getArr()]);\nvar_dump([...arrGen()]);\nvar_dump([...new ArrayIterator(['a', 'b', 'c'])]);\nvar_dump([0, ...$array, ...getArr(), 6, 7, 8, 9, 10, ...arrGen()]);\nvar_dump([0, ...$array, ...$array, 'end']);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-array_unpack-classes.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_unpack/classes.phpt
it("Array unpacking with classes", function () {
expect(parser.parseCode("<?php\nclass C {\n public const FOO = [0, ...self::ARR, 4];\n public const ARR = [1, 2, 3];\n public static $bar = [...self::ARR];\n}\nclass D {\n public const A = [...self::B];\n public const B = [...self::A];\n}\nvar_dump(C::FOO);\nvar_dump(C::$bar);\ntry {\n var_dump(D::A);\n} catch (Error $ex) {\n echo \"Exception: \" . $ex->getMessage() . \"\\n\";\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-array_unpack-in_destructuring.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_unpack/in_destructuring.phpt
it("Spread operator is not supported in destructuring assignments", function () {
expect(parser.parseCode("<?php\n[$head, ...$tail] = [1, 2, 3];\n?>")).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_unpack/in_destructuring_2.phpt
it("Spread operator is not supported in destructuring assignments (only spread)", function () {
expect(parser.parseCode("<?php\n[...$x] = [1, 2, 3];\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-array_unpack-non_integer_keys.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_unpack/non_integer_keys.phpt
it("Array unpacking does not work with non-integer/string keys", function () {
expect(parser.parseCode("<?php\nfunction gen() {\n yield [] => 1;\n yield 1.23 => 123;\n}\ntry {\n [...gen()];\n} catch (Error $ex) {\n echo \"Exception: \" . $ex->getMessage() . \"\\n\";\n}\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-array_unpack-ref1.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_unpack/ref1.phpt
it("Array unpacking with element rc=1", function () {
expect(parser.parseCode("<?php\n$a = 1;\n$b = [&$a]; //array (0 => (refcount=2, is_ref=1)=1)\nunset($a); //array (0 => (refcount=1, is_ref=1)=1)\nvar_dump([...$b]); //array (0 => (refcount=0, is_ref=0)=1)\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-array_unpack-string_keys.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_unpack/string_keys.phpt
it("Array unpacking with string keys", function () {
expect(parser.parseCode("<?php\n// Works with both arrays and Traversables.\n$array = [1, 2, \"foo\" => 3, 4];\nvar_dump([...$array]);\n$iterator = new ArrayIterator([1, 2, \"foo\" => 3, 4]);\nvar_dump([...$iterator]);\n// Test overwriting behavior.\n$array1 = [\"foo\" => 1];\n$array2 = [\"foo\" => 2];\nvar_dump([\"foo\" => 0, ...$array1, ...$array2]);\nvar_dump([\"foo\" => 0, ...$array1, ...$array2, \"foo\" => 3]);\n// Test numeric string key from iterator.\nfunction gen() {\n yield \"42\" => 42;\n}\nvar_dump([...gen()]);\n// Same as previous, but with refcounted string.\nfunction gen2() {\n $foo = \"2\";\n yield \"4\" . $foo => 42;\n}\nvar_dump([...gen2()]);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-array_unpack-undef_var.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_unpack/undef_var.phpt
it("array unpacking with undefined variable", function () {
expect(parser.parseCode("<?php\nvar_dump([...$arr]);\n?>")).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_unpack/unpack_invalid_type_compile_time.phpt
it("Unpacking non-array/Traversable detected at compile-time", function () {
expect(parser.parseCode("<?php\nvar_dump([...42]);\n?>")).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_unpack/unpack_string_keys_compile_time.phpt
it("Unpacking of string keys is supported at compile-time", function () {
expect(parser.parseCode("<?php\nvar_dump([...['a' => 'b']]);\nvar_dump(['a' => 'X', ...['a' => 'b']]);\nvar_dump([...['a' => 'b'], 'a' => 'X']);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-array_unpack_string_keys.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_unpack_string_keys.phpt
it("Using array unpacking in an array literal that also has string keys (OSS-Fuzz #17965)", function () {
expect(parser.parseCode("<?php\n$y = [1, 2, 3];\n$z = \"bar\";\n$x = [...$y, \"foo\" => $z];\nvar_dump($x);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-array_unshift_COW.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_unshift_COW.phpt
it("Tests that array unshift code is correctly dealing with copy on write and splitting on reference", function () {
expect(parser.parseCode("<?php\n $a=array();\n $b=1;\n $c=&$b;\n array_unshift ($a,$b);\n $b=2;\n var_dump ($a);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-array_with_refs_identical.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/array_with_refs_identical.phpt
it("Identical comparison of array with references", function () {
expect(parser.parseCode("<?php\n$foo = 42;\n$array1 = [&$foo];\n$array2 = [$foo];\nvar_dump($array1 === $array2);\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-arrow_functions-001.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/arrow_functions/001.phpt
it("Basic arrow function functionality check", function () {
expect(parser.parseCode("<?php\n$foo = fn() => 1;\nvar_dump($foo());\n$foo = fn($x) => $x;\nvar_dump($foo(2));\n$foo = fn($x, $y) => $x + $y;\nvar_dump($foo(1, 2));\n// Closing over $var\n$var = 4;\n$foo = fn() => $var;\nvar_dump($foo());\n// Not closing over $var, it's a parameter\n$foo = fn($var) => $var;\nvar_dump($foo(5));\n// Close over $var by-value, not by-reference\n$var = 5;\n$foo = fn() => ++$var;\nvar_dump($foo());\nvar_dump($var);\n// Nested arrow functions closing over variable\n$var = 6;\nvar_dump((fn() => fn() => $var)()());\nvar_dump((fn() => function() use($var) { return $var; })()());\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-arrow_functions-002.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/arrow_functions/002.phpt
it("Arrow functions implicit use must be throwing notices only upon actual use", function () {
expect(parser.parseCode("<?php\n$b = 1;\nvar_dump((fn() => $b + $c)());\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-arrow_functions-003.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/arrow_functions/003.phpt
it("Variable-variables inside arrow functions", function () {
expect(parser.parseCode("<?php\n$a = 1;\n$var = \"a\";\n$fn = fn() => $$var;\nvar_dump($fn());\n${5} = 2;\n$fn = fn() => ${5};\nvar_dump($fn());\n?>")).toMatchSnapshot();
});
});
9 changes: 9 additions & 0 deletions test/php-src/Zend-tests-arrow_functions-004.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// eslint-disable prettier/prettier
const parser = require("../main");

describe("php-src tests", function () {
// Zend/tests/arrow_functions/004.phpt
it("Auto-globals in arrow functions", function () {
expect(parser.parseCode("<?php\n// This should work, but *not* generate a binding for $GLOBALS\n$a = 123;\n$fn = fn() => $GLOBALS['a'];\nvar_dump($fn());\n?>")).toMatchSnapshot();
});
});
Loading