mirror of
https://github.com/danog/parser.git
synced 2024-11-26 20:04:57 +01:00
fix: use by reference in anonymous functions (#10)
This commit is contained in:
parent
848da45855
commit
6c27fc8599
@ -48,6 +48,8 @@ impl Parser {
|
||||
while state.current.kind != TokenKind::RightParen {
|
||||
let mut by_ref = false;
|
||||
if state.current.kind == TokenKind::Ampersand {
|
||||
state.next();
|
||||
|
||||
by_ref = true;
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ impl State {
|
||||
let mut iter = tokens.into_iter();
|
||||
|
||||
Self {
|
||||
stack: VecDeque::new(),
|
||||
stack: VecDeque::with_capacity(3),
|
||||
current: iter.next().unwrap_or_default(),
|
||||
peek: iter.next().unwrap_or_default(),
|
||||
iter,
|
||||
|
309
tests/0178/ast.txt
Normal file
309
tests/0178/ast.txt
Normal file
@ -0,0 +1,309 @@
|
||||
[
|
||||
Declare {
|
||||
declares: [
|
||||
DeclareItem {
|
||||
key: Identifier {
|
||||
name: "strict_types",
|
||||
},
|
||||
value: LiteralInteger {
|
||||
i: 1,
|
||||
},
|
||||
},
|
||||
],
|
||||
body: [],
|
||||
},
|
||||
Namespace {
|
||||
name: "Psl\Internal",
|
||||
body: [
|
||||
Noop,
|
||||
Use {
|
||||
uses: [
|
||||
Use {
|
||||
name: Identifier {
|
||||
name: "Closure",
|
||||
},
|
||||
alias: None,
|
||||
},
|
||||
],
|
||||
kind: Normal,
|
||||
},
|
||||
Use {
|
||||
uses: [
|
||||
Use {
|
||||
name: Identifier {
|
||||
name: "Psl\Str",
|
||||
},
|
||||
alias: None,
|
||||
},
|
||||
],
|
||||
kind: Normal,
|
||||
},
|
||||
Use {
|
||||
uses: [
|
||||
Use {
|
||||
name: Identifier {
|
||||
name: "restore_error_handler",
|
||||
},
|
||||
alias: None,
|
||||
},
|
||||
],
|
||||
kind: Function,
|
||||
},
|
||||
Use {
|
||||
uses: [
|
||||
Use {
|
||||
name: Identifier {
|
||||
name: "set_error_handler",
|
||||
},
|
||||
alias: None,
|
||||
},
|
||||
],
|
||||
kind: Function,
|
||||
},
|
||||
Function {
|
||||
name: Identifier {
|
||||
name: "box",
|
||||
},
|
||||
params: [
|
||||
Param {
|
||||
name: Variable {
|
||||
name: "fun",
|
||||
},
|
||||
type: Some(
|
||||
Identifier(
|
||||
Identifier {
|
||||
name: "Closure",
|
||||
},
|
||||
),
|
||||
),
|
||||
variadic: false,
|
||||
default: None,
|
||||
flags: [],
|
||||
by_ref: false,
|
||||
},
|
||||
],
|
||||
body: [
|
||||
Expression {
|
||||
expr: Infix {
|
||||
lhs: Variable {
|
||||
name: "last_message",
|
||||
},
|
||||
op: Assign,
|
||||
rhs: Null,
|
||||
},
|
||||
},
|
||||
Expression {
|
||||
expr: Call {
|
||||
target: Identifier {
|
||||
name: "set_error_handler",
|
||||
},
|
||||
args: [
|
||||
Arg {
|
||||
name: None,
|
||||
value: Closure {
|
||||
params: [
|
||||
Param {
|
||||
name: Variable {
|
||||
name: "_type",
|
||||
},
|
||||
type: Some(
|
||||
Integer,
|
||||
),
|
||||
variadic: false,
|
||||
default: None,
|
||||
flags: [],
|
||||
by_ref: false,
|
||||
},
|
||||
Param {
|
||||
name: Variable {
|
||||
name: "message",
|
||||
},
|
||||
type: Some(
|
||||
String,
|
||||
),
|
||||
variadic: false,
|
||||
default: None,
|
||||
flags: [],
|
||||
by_ref: false,
|
||||
},
|
||||
],
|
||||
uses: [
|
||||
ClosureUse {
|
||||
var: Variable {
|
||||
name: "last_message",
|
||||
},
|
||||
by_ref: true,
|
||||
},
|
||||
],
|
||||
return_type: None,
|
||||
body: [
|
||||
Expression {
|
||||
expr: Infix {
|
||||
lhs: Variable {
|
||||
name: "last_message",
|
||||
},
|
||||
op: Assign,
|
||||
rhs: Variable {
|
||||
name: "message",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
static: true,
|
||||
by_ref: false,
|
||||
},
|
||||
unpack: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
If {
|
||||
condition: Infix {
|
||||
lhs: Infix {
|
||||
lhs: Null,
|
||||
op: NotIdentical,
|
||||
rhs: Variable {
|
||||
name: "last_message",
|
||||
},
|
||||
},
|
||||
op: And,
|
||||
rhs: Call {
|
||||
target: Identifier {
|
||||
name: "Str\contains",
|
||||
},
|
||||
args: [
|
||||
Arg {
|
||||
name: None,
|
||||
value: Variable {
|
||||
name: "last_message",
|
||||
},
|
||||
unpack: false,
|
||||
},
|
||||
Arg {
|
||||
name: None,
|
||||
value: LiteralString {
|
||||
value: "): ",
|
||||
},
|
||||
unpack: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
then: [
|
||||
Expression {
|
||||
expr: Infix {
|
||||
lhs: Variable {
|
||||
name: "last_message",
|
||||
},
|
||||
op: Assign,
|
||||
rhs: Call {
|
||||
target: Identifier {
|
||||
name: "Str\after",
|
||||
},
|
||||
args: [
|
||||
Arg {
|
||||
name: None,
|
||||
value: Call {
|
||||
target: Identifier {
|
||||
name: "Str\lowercase",
|
||||
},
|
||||
args: [
|
||||
Arg {
|
||||
name: None,
|
||||
value: Variable {
|
||||
name: "last_message",
|
||||
},
|
||||
unpack: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
unpack: false,
|
||||
},
|
||||
Arg {
|
||||
name: None,
|
||||
value: LiteralString {
|
||||
value: "): ",
|
||||
},
|
||||
unpack: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
else_ifs: [],
|
||||
else: None,
|
||||
},
|
||||
Try {
|
||||
body: [
|
||||
Expression {
|
||||
expr: Infix {
|
||||
lhs: Variable {
|
||||
name: "value",
|
||||
},
|
||||
op: Assign,
|
||||
rhs: Call {
|
||||
target: Variable {
|
||||
name: "fun",
|
||||
},
|
||||
args: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
Expression {
|
||||
expr: Infix {
|
||||
lhs: Variable {
|
||||
name: "result",
|
||||
},
|
||||
op: Assign,
|
||||
rhs: Array {
|
||||
items: [
|
||||
ArrayItem {
|
||||
key: None,
|
||||
value: Variable {
|
||||
name: "value",
|
||||
},
|
||||
unpack: false,
|
||||
},
|
||||
ArrayItem {
|
||||
key: None,
|
||||
value: Variable {
|
||||
name: "last_message",
|
||||
},
|
||||
unpack: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
Return {
|
||||
value: Some(
|
||||
Variable {
|
||||
name: "result",
|
||||
},
|
||||
),
|
||||
},
|
||||
],
|
||||
catches: [],
|
||||
finally: Some(
|
||||
[
|
||||
Expression {
|
||||
expr: Call {
|
||||
target: Identifier {
|
||||
name: "restore_error_handler",
|
||||
},
|
||||
args: [],
|
||||
},
|
||||
},
|
||||
],
|
||||
),
|
||||
},
|
||||
],
|
||||
return_type: Some(
|
||||
Array,
|
||||
),
|
||||
by_ref: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
61
tests/0178/code.php
Normal file
61
tests/0178/code.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
// The following code was taken from of PSL.
|
||||
//
|
||||
// https://github.com/azjezz/psl/blob/657ce9888be47cee49418989420b83661f7cf1c4/src/Psl/Internal/box.php
|
||||
//
|
||||
// Code subject to the MIT license (https://github.com/azjezz/psl/blob/657ce9888be47cee49418989420b83661f7cf1c4/LICENSE).
|
||||
//
|
||||
// Copyright (c) 2019-2022 Saif Eddin Gmati <azjezz@protonmail.com>
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Psl\Internal;
|
||||
|
||||
use Closure;
|
||||
use Psl\Str;
|
||||
|
||||
use function restore_error_handler;
|
||||
use function set_error_handler;
|
||||
|
||||
/**
|
||||
* @template T
|
||||
*
|
||||
* @param (Closure(): T) $fun
|
||||
*
|
||||
* @return array{0: T, 1: ?string}
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @psalm-suppress MissingThrowsDocblock
|
||||
*/
|
||||
function box(Closure $fun): array
|
||||
{
|
||||
$last_message = null;
|
||||
/** @psalm-suppress InvalidArgument */
|
||||
set_error_handler(static function (int $_type, string $message) use (&$last_message) {
|
||||
$last_message = $message;
|
||||
});
|
||||
|
||||
/**
|
||||
* @var string|null $last_message
|
||||
*/
|
||||
if (null !== $last_message && Str\contains($last_message, '): ')) {
|
||||
$last_message = Str\after(
|
||||
Str\lowercase($last_message),
|
||||
// how i feel toward PHP error handling:
|
||||
'): '
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
$value = $fun();
|
||||
|
||||
/** @var array{0: T, 1: ?string} $result */
|
||||
$result = [$value, $last_message];
|
||||
|
||||
return $result;
|
||||
} finally {
|
||||
restore_error_handler();
|
||||
}
|
||||
}
|
1001
tests/0178/tokens.txt
Normal file
1001
tests/0178/tokens.txt
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user