mirror of
https://github.com/danog/parser.git
synced 2024-11-30 04:29:13 +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 key: Option<Expression>,
|
||||||
pub value: Expression,
|
pub value: Expression,
|
||||||
pub unpack: bool,
|
pub unpack: bool,
|
||||||
|
pub by_ref: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
|
@ -1187,17 +1187,46 @@ impl Parser {
|
|||||||
false
|
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)?;
|
let mut value = self.expression(state, Precedence::Lowest)?;
|
||||||
|
|
||||||
// TODO: return error for `[...$a => $b]`.
|
// TODO: return error for `[...$a => $b]`.
|
||||||
if state.current.kind == TokenKind::DoubleArrow {
|
if state.current.kind == TokenKind::DoubleArrow {
|
||||||
state.next();
|
state.next();
|
||||||
|
|
||||||
|
if by_ref {
|
||||||
|
return Err(ParseError::UnexpectedToken(
|
||||||
|
TokenKind::Ampersand.to_string(),
|
||||||
|
amper_span,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
key = Some(value);
|
key = Some(value);
|
||||||
|
|
||||||
|
by_ref = if state.current.kind == TokenKind::Ampersand {
|
||||||
|
state.next();
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
value = self.expression(state, Precedence::Lowest)?;
|
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 {
|
if state.current.kind == TokenKind::Comma {
|
||||||
state.next();
|
state.next();
|
||||||
@ -1227,6 +1256,7 @@ impl Parser {
|
|||||||
key: None,
|
key: None,
|
||||||
value: Expression::Empty,
|
value: Expression::Empty,
|
||||||
unpack: false,
|
unpack: false,
|
||||||
|
by_ref: false,
|
||||||
});
|
});
|
||||||
state.next();
|
state.next();
|
||||||
continue;
|
continue;
|
||||||
@ -1240,16 +1270,42 @@ impl Parser {
|
|||||||
false
|
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 {
|
if state.current.kind == TokenKind::DoubleArrow {
|
||||||
state.next();
|
state.next();
|
||||||
|
|
||||||
|
if by_ref {
|
||||||
|
return Err(ParseError::UnexpectedToken(
|
||||||
|
TokenKind::Ampersand.to_string(),
|
||||||
|
amper_span,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
key = Some(value);
|
key = Some(value);
|
||||||
|
by_ref = if state.current.kind == TokenKind::Ampersand {
|
||||||
|
state.next();
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
value = self.expression(state, Precedence::Lowest)?;
|
value = self.expression(state, Precedence::Lowest)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
items.push(ArrayItem { key, value, unpack });
|
items.push(ArrayItem {
|
||||||
|
key,
|
||||||
|
value,
|
||||||
|
unpack,
|
||||||
|
by_ref,
|
||||||
|
});
|
||||||
|
|
||||||
state.skip_comments();
|
state.skip_comments();
|
||||||
if state.current.kind == TokenKind::Comma {
|
if state.current.kind == TokenKind::Comma {
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
unpack: false,
|
unpack: false,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
ArrayItem {
|
ArrayItem {
|
||||||
key: Some(
|
key: Some(
|
||||||
@ -66,6 +67,7 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
unpack: false,
|
unpack: false,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -70,6 +70,7 @@
|
|||||||
name: "baz",
|
name: "baz",
|
||||||
},
|
},
|
||||||
unpack: false,
|
unpack: false,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
ArrayItem {
|
ArrayItem {
|
||||||
key: None,
|
key: None,
|
||||||
@ -77,6 +78,7 @@
|
|||||||
name: "car",
|
name: "car",
|
||||||
},
|
},
|
||||||
unpack: false,
|
unpack: false,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
i: 1,
|
i: 1,
|
||||||
},
|
},
|
||||||
unpack: false,
|
unpack: false,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
ArrayItem {
|
ArrayItem {
|
||||||
key: None,
|
key: None,
|
||||||
@ -15,11 +16,13 @@
|
|||||||
i: 2,
|
i: 2,
|
||||||
},
|
},
|
||||||
unpack: false,
|
unpack: false,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
ArrayItem {
|
ArrayItem {
|
||||||
key: None,
|
key: None,
|
||||||
value: Empty,
|
value: Empty,
|
||||||
unpack: false,
|
unpack: false,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
ArrayItem {
|
ArrayItem {
|
||||||
key: None,
|
key: None,
|
||||||
@ -27,6 +30,7 @@
|
|||||||
i: 4,
|
i: 4,
|
||||||
},
|
},
|
||||||
unpack: false,
|
unpack: false,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
items: [],
|
items: [],
|
||||||
},
|
},
|
||||||
unpack: true,
|
unpack: true,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -12,10 +12,12 @@
|
|||||||
i: 1,
|
i: 1,
|
||||||
},
|
},
|
||||||
unpack: false,
|
unpack: false,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
unpack: true,
|
unpack: true,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
ArrayItem {
|
ArrayItem {
|
||||||
key: None,
|
key: None,
|
||||||
@ -27,10 +29,12 @@
|
|||||||
i: 2,
|
i: 2,
|
||||||
},
|
},
|
||||||
unpack: false,
|
unpack: false,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
unpack: true,
|
unpack: true,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -269,6 +269,7 @@
|
|||||||
name: "value",
|
name: "value",
|
||||||
},
|
},
|
||||||
unpack: false,
|
unpack: false,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
ArrayItem {
|
ArrayItem {
|
||||||
key: None,
|
key: None,
|
||||||
@ -276,6 +277,7 @@
|
|||||||
name: "last_message",
|
name: "last_message",
|
||||||
},
|
},
|
||||||
unpack: false,
|
unpack: false,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
name: "a",
|
name: "a",
|
||||||
},
|
},
|
||||||
unpack: false,
|
unpack: false,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
ArrayItem {
|
ArrayItem {
|
||||||
key: None,
|
key: None,
|
||||||
@ -20,6 +21,7 @@
|
|||||||
name: "b",
|
name: "b",
|
||||||
},
|
},
|
||||||
unpack: false,
|
unpack: false,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
ArrayItem {
|
ArrayItem {
|
||||||
key: None,
|
key: None,
|
||||||
@ -27,6 +29,7 @@
|
|||||||
name: "c",
|
name: "c",
|
||||||
},
|
},
|
||||||
unpack: false,
|
unpack: false,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
ArrayItem {
|
ArrayItem {
|
||||||
key: None,
|
key: None,
|
||||||
@ -34,6 +37,7 @@
|
|||||||
name: "d",
|
name: "d",
|
||||||
},
|
},
|
||||||
unpack: false,
|
unpack: false,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
name: "a",
|
name: "a",
|
||||||
},
|
},
|
||||||
unpack: false,
|
unpack: false,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
ArrayItem {
|
ArrayItem {
|
||||||
key: None,
|
key: None,
|
||||||
@ -20,6 +21,7 @@
|
|||||||
name: "b",
|
name: "b",
|
||||||
},
|
},
|
||||||
unpack: false,
|
unpack: false,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
ArrayItem {
|
ArrayItem {
|
||||||
key: None,
|
key: None,
|
||||||
@ -27,6 +29,7 @@
|
|||||||
name: "c",
|
name: "c",
|
||||||
},
|
},
|
||||||
unpack: false,
|
unpack: false,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
ArrayItem {
|
ArrayItem {
|
||||||
key: None,
|
key: None,
|
||||||
@ -34,6 +37,7 @@
|
|||||||
name: "d",
|
name: "d",
|
||||||
},
|
},
|
||||||
unpack: false,
|
unpack: false,
|
||||||
|
by_ref: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
args: [],
|
args: [],
|
||||||
},
|
},
|
||||||
unpack: false,
|
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",
|
"src/Symfony/Component/Config/Tests/Fixtures/ParseError.php",
|
||||||
// FIXME: Remove this one once I've found the energy to sort out heredocs / nowdocs.
|
// 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/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