mirror of
https://github.com/danog/parser.git
synced 2024-11-26 20:04:57 +01:00
parser: allow passing array items by ref
This commit is contained in:
parent
5815f65737
commit
b1f10231e0
@ -814,6 +814,7 @@ pub struct ArrayItem {
|
||||
pub key: Option<Expression>,
|
||||
pub value: Expression,
|
||||
pub unpack: bool,
|
||||
pub by_ref: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
|
@ -1187,17 +1187,46 @@ impl Parser {
|
||||
false
|
||||
};
|
||||
|
||||
let (mut by_ref, amper_span) = if state.current.kind == TokenKind::Ampersand
|
||||
{
|
||||
let span = state.current.span;
|
||||
state.next();
|
||||
(true, span)
|
||||
} else {
|
||||
(false, (0, 0))
|
||||
};
|
||||
|
||||
let mut value = self.expression(state, Precedence::Lowest)?;
|
||||
|
||||
// TODO: return error for `[...$a => $b]`.
|
||||
if state.current.kind == TokenKind::DoubleArrow {
|
||||
state.next();
|
||||
|
||||
if by_ref {
|
||||
return Err(ParseError::UnexpectedToken(
|
||||
TokenKind::Ampersand.to_string(),
|
||||
amper_span,
|
||||
));
|
||||
}
|
||||
|
||||
key = Some(value);
|
||||
|
||||
by_ref = if state.current.kind == TokenKind::Ampersand {
|
||||
state.next();
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
value = self.expression(state, Precedence::Lowest)?;
|
||||
}
|
||||
|
||||
items.push(ArrayItem { key, value, unpack });
|
||||
items.push(ArrayItem {
|
||||
key,
|
||||
value,
|
||||
unpack,
|
||||
by_ref,
|
||||
});
|
||||
|
||||
if state.current.kind == TokenKind::Comma {
|
||||
state.next();
|
||||
@ -1227,6 +1256,7 @@ impl Parser {
|
||||
key: None,
|
||||
value: Expression::Empty,
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
});
|
||||
state.next();
|
||||
continue;
|
||||
@ -1240,16 +1270,42 @@ impl Parser {
|
||||
false
|
||||
};
|
||||
|
||||
let mut value = self.expression(state, Precedence::Lowest)?;
|
||||
let (mut by_ref, amper_span) = if state.current.kind == TokenKind::Ampersand
|
||||
{
|
||||
let span = state.current.span;
|
||||
state.next();
|
||||
(true, span)
|
||||
} else {
|
||||
(false, (0, 0))
|
||||
};
|
||||
|
||||
let mut value = self.expression(state, Precedence::Lowest)?;
|
||||
if state.current.kind == TokenKind::DoubleArrow {
|
||||
state.next();
|
||||
|
||||
if by_ref {
|
||||
return Err(ParseError::UnexpectedToken(
|
||||
TokenKind::Ampersand.to_string(),
|
||||
amper_span,
|
||||
));
|
||||
}
|
||||
|
||||
key = Some(value);
|
||||
by_ref = if state.current.kind == TokenKind::Ampersand {
|
||||
state.next();
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
value = self.expression(state, Precedence::Lowest)?;
|
||||
}
|
||||
|
||||
items.push(ArrayItem { key, value, unpack });
|
||||
items.push(ArrayItem {
|
||||
key,
|
||||
value,
|
||||
unpack,
|
||||
by_ref,
|
||||
});
|
||||
|
||||
state.skip_comments();
|
||||
if state.current.kind == TokenKind::Comma {
|
||||
|
@ -37,6 +37,7 @@
|
||||
},
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
},
|
||||
ArrayItem {
|
||||
key: Some(
|
||||
@ -66,6 +67,7 @@
|
||||
},
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -70,6 +70,7 @@
|
||||
name: "baz",
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
},
|
||||
ArrayItem {
|
||||
key: None,
|
||||
@ -77,6 +78,7 @@
|
||||
name: "car",
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -8,6 +8,7 @@
|
||||
i: 1,
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
},
|
||||
ArrayItem {
|
||||
key: None,
|
||||
@ -15,11 +16,13 @@
|
||||
i: 2,
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
},
|
||||
ArrayItem {
|
||||
key: None,
|
||||
value: Empty,
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
},
|
||||
ArrayItem {
|
||||
key: None,
|
||||
@ -27,6 +30,7 @@
|
||||
i: 4,
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -8,6 +8,7 @@
|
||||
items: [],
|
||||
},
|
||||
unpack: true,
|
||||
by_ref: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -12,10 +12,12 @@
|
||||
i: 1,
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
unpack: true,
|
||||
by_ref: false,
|
||||
},
|
||||
ArrayItem {
|
||||
key: None,
|
||||
@ -27,10 +29,12 @@
|
||||
i: 2,
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
unpack: true,
|
||||
by_ref: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -269,6 +269,7 @@
|
||||
name: "value",
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
},
|
||||
ArrayItem {
|
||||
key: None,
|
||||
@ -276,6 +277,7 @@
|
||||
name: "last_message",
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -13,6 +13,7 @@
|
||||
name: "a",
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
},
|
||||
ArrayItem {
|
||||
key: None,
|
||||
@ -20,6 +21,7 @@
|
||||
name: "b",
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
},
|
||||
ArrayItem {
|
||||
key: None,
|
||||
@ -27,6 +29,7 @@
|
||||
name: "c",
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
},
|
||||
ArrayItem {
|
||||
key: None,
|
||||
@ -34,6 +37,7 @@
|
||||
name: "d",
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -13,6 +13,7 @@
|
||||
name: "a",
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
},
|
||||
ArrayItem {
|
||||
key: None,
|
||||
@ -20,6 +21,7 @@
|
||||
name: "b",
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
},
|
||||
ArrayItem {
|
||||
key: None,
|
||||
@ -27,6 +29,7 @@
|
||||
name: "c",
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
},
|
||||
ArrayItem {
|
||||
key: None,
|
||||
@ -34,6 +37,7 @@
|
||||
name: "d",
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -11,6 +11,7 @@
|
||||
args: [],
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
16
tests/0246/ast.txt
Normal file
16
tests/0246/ast.txt
Normal file
@ -0,0 +1,16 @@
|
||||
[
|
||||
Expression {
|
||||
expr: Array {
|
||||
items: [
|
||||
ArrayItem {
|
||||
key: None,
|
||||
value: Variable {
|
||||
name: "foo",
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
3
tests/0246/code.php
Normal file
3
tests/0246/code.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
[&$foo];
|
48
tests/0246/tokens.txt
Normal file
48
tests/0246/tokens.txt
Normal file
@ -0,0 +1,48 @@
|
||||
[
|
||||
Token {
|
||||
kind: OpenTag(
|
||||
Full,
|
||||
),
|
||||
span: (
|
||||
1,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBracket,
|
||||
span: (
|
||||
3,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Ampersand,
|
||||
span: (
|
||||
3,
|
||||
2,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Variable(
|
||||
"foo",
|
||||
),
|
||||
span: (
|
||||
3,
|
||||
3,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBracket,
|
||||
span: (
|
||||
3,
|
||||
7,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: SemiColon,
|
||||
span: (
|
||||
3,
|
||||
8,
|
||||
),
|
||||
},
|
||||
]
|
3
tests/0247/code.php
Normal file
3
tests/0247/code.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
[&$foo => $bar];
|
1
tests/0247/parser-error.txt
Normal file
1
tests/0247/parser-error.txt
Normal file
@ -0,0 +1 @@
|
||||
UnexpectedToken("&", (3, 2)) -> Parse Error: Unexpected token & on line 3 column 2
|
64
tests/0247/tokens.txt
Normal file
64
tests/0247/tokens.txt
Normal file
@ -0,0 +1,64 @@
|
||||
[
|
||||
Token {
|
||||
kind: OpenTag(
|
||||
Full,
|
||||
),
|
||||
span: (
|
||||
1,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBracket,
|
||||
span: (
|
||||
3,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Ampersand,
|
||||
span: (
|
||||
3,
|
||||
2,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Variable(
|
||||
"foo",
|
||||
),
|
||||
span: (
|
||||
3,
|
||||
3,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: DoubleArrow,
|
||||
span: (
|
||||
3,
|
||||
8,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Variable(
|
||||
"bar",
|
||||
),
|
||||
span: (
|
||||
3,
|
||||
11,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBracket,
|
||||
span: (
|
||||
3,
|
||||
15,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: SemiColon,
|
||||
span: (
|
||||
3,
|
||||
16,
|
||||
),
|
||||
},
|
||||
]
|
20
tests/0248/ast.txt
Normal file
20
tests/0248/ast.txt
Normal file
@ -0,0 +1,20 @@
|
||||
[
|
||||
Expression {
|
||||
expr: Array {
|
||||
items: [
|
||||
ArrayItem {
|
||||
key: Some(
|
||||
Variable {
|
||||
name: "foo",
|
||||
},
|
||||
),
|
||||
value: Variable {
|
||||
name: "bar",
|
||||
},
|
||||
unpack: false,
|
||||
by_ref: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
3
tests/0248/code.php
Normal file
3
tests/0248/code.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
[$foo => &$bar];
|
64
tests/0248/tokens.txt
Normal file
64
tests/0248/tokens.txt
Normal file
@ -0,0 +1,64 @@
|
||||
[
|
||||
Token {
|
||||
kind: OpenTag(
|
||||
Full,
|
||||
),
|
||||
span: (
|
||||
1,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBracket,
|
||||
span: (
|
||||
3,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Variable(
|
||||
"foo",
|
||||
),
|
||||
span: (
|
||||
3,
|
||||
2,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: DoubleArrow,
|
||||
span: (
|
||||
3,
|
||||
7,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Ampersand,
|
||||
span: (
|
||||
3,
|
||||
10,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Variable(
|
||||
"bar",
|
||||
),
|
||||
span: (
|
||||
3,
|
||||
11,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBracket,
|
||||
span: (
|
||||
3,
|
||||
15,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: SemiColon,
|
||||
span: (
|
||||
3,
|
||||
16,
|
||||
),
|
||||
},
|
||||
]
|
@ -40,7 +40,7 @@ fn third_party_3_symfony_framework() {
|
||||
"src/Symfony/Component/Config/Tests/Fixtures/ParseError.php",
|
||||
// FIXME: Remove this one once I've found the energy to sort out heredocs / nowdocs.
|
||||
"src/Symfony/Component/DependencyInjection/LazyProxy/PhpDumper/LazyServiceDumper.php",
|
||||
"src/Symfony/Component/Cache/Tests/Traits/RedisProxiesTest.php"
|
||||
"src/Symfony/Component/Cache/Tests/Traits/RedisProxiesTest.php",
|
||||
],
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user