mirror of
https://github.com/danog/parser.git
synced 2024-11-26 20:04:57 +01:00
chore: remove fallback expression parser (#181)
Signed-off-by: azjezz <azjezz@protonmail.com>
This commit is contained in:
parent
00834ed3ff
commit
bd2023c3c4
@ -1514,6 +1514,13 @@ fn identifier_to_keyword(ident: &[u8]) -> Option<TokenKind> {
|
||||
b"var" => TokenKind::Var,
|
||||
b"yield" => TokenKind::Yield,
|
||||
b"__DIR__" => TokenKind::DirConstant,
|
||||
b"__FILE__" => TokenKind::FileConstant,
|
||||
b"__LINE__" => TokenKind::LineConstant,
|
||||
b"__FUNCTION__" => TokenKind::FunctionConstant,
|
||||
b"__CLASS__" => TokenKind::ClassConstant,
|
||||
b"__METHOD__" => TokenKind::MethodConstant,
|
||||
b"__TRAIT__" => TokenKind::TraitConstant,
|
||||
b"__NAMESPACE__" => TokenKind::NamespaceConstant,
|
||||
b"while" => TokenKind::While,
|
||||
b"insteadof" => TokenKind::Insteadof,
|
||||
b"list" => TokenKind::List,
|
||||
|
@ -391,6 +391,7 @@ pub enum Expression {
|
||||
Empty,
|
||||
VariadicPlaceholder,
|
||||
ErrorSuppress {
|
||||
span: Span,
|
||||
expr: Box<Self>,
|
||||
},
|
||||
Increment {
|
||||
@ -415,6 +416,7 @@ pub enum Expression {
|
||||
rhs: Box<Self>,
|
||||
},
|
||||
Include {
|
||||
span: Span,
|
||||
kind: IncludeKind,
|
||||
path: Box<Expression>,
|
||||
},
|
||||
@ -496,9 +498,11 @@ pub enum Expression {
|
||||
},
|
||||
Null,
|
||||
BooleanNot {
|
||||
span: Span,
|
||||
value: Box<Self>,
|
||||
},
|
||||
MagicConst {
|
||||
span: Span,
|
||||
constant: MagicConst,
|
||||
},
|
||||
Ternary {
|
||||
@ -529,24 +533,31 @@ pub enum Expression {
|
||||
value: Box<Self>,
|
||||
},
|
||||
Negate {
|
||||
span: Span,
|
||||
value: Box<Self>,
|
||||
},
|
||||
UnaryPlus {
|
||||
span: Span,
|
||||
value: Box<Self>,
|
||||
},
|
||||
BitwiseNot {
|
||||
span: Span,
|
||||
value: Box<Self>,
|
||||
},
|
||||
PreDecrement {
|
||||
span: Span,
|
||||
value: Box<Self>,
|
||||
},
|
||||
PreIncrement {
|
||||
span: Span,
|
||||
value: Box<Self>,
|
||||
},
|
||||
Print {
|
||||
span: Span,
|
||||
value: Box<Self>,
|
||||
},
|
||||
Cast {
|
||||
span: Span,
|
||||
kind: CastKind,
|
||||
value: Box<Self>,
|
||||
},
|
||||
@ -578,7 +589,14 @@ pub struct MatchArm {
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub enum MagicConst {
|
||||
Dir,
|
||||
Directory,
|
||||
File,
|
||||
Line,
|
||||
Class,
|
||||
Function,
|
||||
Method,
|
||||
Namespace,
|
||||
Trait,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
|
@ -188,7 +188,7 @@ fn create(state: &mut State) -> ParseResult<Expression> {
|
||||
}
|
||||
|
||||
macro_rules! expressions {
|
||||
($(#[before($else:ident), current($( $current:pat_param )|+) $(, peek($( $peek:pat_param )|+))?] $expr:ident($out:expr))+) => {
|
||||
($(#[before($else:ident), current($(|)? $( $current:pat_param )|+) $(, peek($(|)? $( $peek:pat_param )|+))?] $expr:ident($out:expr))+) => {
|
||||
$(
|
||||
#[inline(never)]
|
||||
fn $expr(state: &mut State) -> ParseResult<Expression> {
|
||||
@ -481,107 +481,286 @@ expressions! {
|
||||
arrays::legacy_array_expression(state)
|
||||
})
|
||||
|
||||
#[before(fallback), current(TokenKind::LeftBracket)]
|
||||
#[before(new), current(TokenKind::LeftBracket)]
|
||||
left_bracket(|state: &mut State| {
|
||||
arrays::array_expression(state)
|
||||
})
|
||||
|
||||
#[before(directory_magic_constant), current(TokenKind::New)]
|
||||
new(|state: &mut State| {
|
||||
state.next();
|
||||
let target = match state.current.kind {
|
||||
TokenKind::Self_ => {
|
||||
if !state.has_class_scope {
|
||||
return Err(ParseError::CannotFindTypeInCurrentScope(
|
||||
state.current.kind.to_string(),
|
||||
state.current.span,
|
||||
));
|
||||
}
|
||||
|
||||
state.next();
|
||||
|
||||
Expression::Self_
|
||||
}
|
||||
TokenKind::Static => {
|
||||
if !state.has_class_scope {
|
||||
return Err(ParseError::CannotFindTypeInCurrentScope(
|
||||
state.current.kind.to_string(),
|
||||
state.current.span,
|
||||
));
|
||||
}
|
||||
|
||||
state.next();
|
||||
|
||||
Expression::Static
|
||||
}
|
||||
TokenKind::Parent => {
|
||||
if !state.has_class_scope {
|
||||
return Err(ParseError::CannotFindTypeInCurrentScope(
|
||||
state.current.kind.to_string(),
|
||||
state.current.span,
|
||||
));
|
||||
}
|
||||
|
||||
state.next();
|
||||
|
||||
Expression::Parent
|
||||
}
|
||||
_ => clone_or_new_precedence(state)?,
|
||||
};
|
||||
|
||||
let mut args = vec![];
|
||||
if state.current.kind == TokenKind::LeftParen {
|
||||
args = parameters::args_list(state)?;
|
||||
}
|
||||
|
||||
Ok(Expression::New{target:Box::new(target),args,})
|
||||
})
|
||||
|
||||
#[before(file_magic_constant), current(TokenKind::DirConstant)]
|
||||
directory_magic_constant(|state: &mut State| {
|
||||
let span = state.current.span;
|
||||
state.next();
|
||||
|
||||
Ok(Expression::MagicConst {
|
||||
span,
|
||||
constant: MagicConst::Directory
|
||||
})
|
||||
})
|
||||
|
||||
#[before(line_magic_constant), current(TokenKind::FileConstant)]
|
||||
file_magic_constant(|state: &mut State| {
|
||||
let span = state.current.span;
|
||||
state.next();
|
||||
|
||||
Ok(Expression::MagicConst {
|
||||
span,
|
||||
constant: MagicConst::File
|
||||
})
|
||||
})
|
||||
|
||||
#[before(function_magic_constant), current(TokenKind::LineConstant)]
|
||||
line_magic_constant(|state: &mut State| {
|
||||
let span = state.current.span;
|
||||
state.next();
|
||||
|
||||
Ok(Expression::MagicConst {
|
||||
span,
|
||||
constant: MagicConst::Line
|
||||
})
|
||||
})
|
||||
|
||||
#[before(class_magic_constant), current(TokenKind::FunctionConstant)]
|
||||
function_magic_constant(|state: &mut State| {
|
||||
let span = state.current.span;
|
||||
state.next();
|
||||
|
||||
Ok(Expression::MagicConst {
|
||||
span,
|
||||
constant: MagicConst::Function,
|
||||
})
|
||||
})
|
||||
|
||||
#[before(method_magic_constant), current(TokenKind::ClassConstant)]
|
||||
class_magic_constant(|state: &mut State| {
|
||||
let span = state.current.span;
|
||||
state.next();
|
||||
|
||||
Ok(Expression::MagicConst {
|
||||
span,
|
||||
constant: MagicConst::Class,
|
||||
})
|
||||
})
|
||||
|
||||
#[before(namespace_magic_constant), current(TokenKind::MethodConstant)]
|
||||
method_magic_constant(|state: &mut State| {
|
||||
let span = state.current.span;
|
||||
state.next();
|
||||
|
||||
Ok(Expression::MagicConst {
|
||||
span,
|
||||
constant: MagicConst::Method,
|
||||
})
|
||||
})
|
||||
|
||||
#[before(trait_magic_constant), current(TokenKind::NamespaceConstant)]
|
||||
namespace_magic_constant(|state: &mut State| {
|
||||
let span = state.current.span;
|
||||
state.next();
|
||||
|
||||
Ok(Expression::MagicConst {
|
||||
span,
|
||||
constant: MagicConst::Namespace,
|
||||
})
|
||||
})
|
||||
|
||||
#[before(include), current(TokenKind::TraitConstant)]
|
||||
trait_magic_constant(|state: &mut State| {
|
||||
let span = state.current.span;
|
||||
state.next();
|
||||
|
||||
Ok(Expression::MagicConst {
|
||||
span,
|
||||
constant: MagicConst::Trait
|
||||
})
|
||||
})
|
||||
|
||||
#[before(cast_prefix), current(TokenKind::Include | TokenKind::IncludeOnce | TokenKind::Require | TokenKind::RequireOnce)]
|
||||
include(|state: &mut State| {
|
||||
let kind: IncludeKind = (&state.current.kind).into();
|
||||
let span = state.current.span;
|
||||
|
||||
state.next();
|
||||
|
||||
let path = lowest_precedence(state)?;
|
||||
|
||||
Ok(Expression::Include {
|
||||
span,
|
||||
kind,
|
||||
path:Box::new(path)
|
||||
})
|
||||
})
|
||||
|
||||
#[before(numeric_prefix), current(
|
||||
| TokenKind::StringCast | TokenKind::BinaryCast | TokenKind::ObjectCast
|
||||
| TokenKind::BoolCast | TokenKind::BooleanCast | TokenKind::IntCast
|
||||
| TokenKind::IntegerCast | TokenKind::FloatCast | TokenKind::DoubleCast
|
||||
| TokenKind::RealCast | TokenKind::UnsetCast | TokenKind::ArrayCast
|
||||
)]
|
||||
cast_prefix(|state: &mut State| {
|
||||
let span = state.current.span;
|
||||
let kind = state.current.kind.clone().into();
|
||||
|
||||
state.next();
|
||||
|
||||
let rhs = for_precedence(state, Precedence::Prefix)?;
|
||||
|
||||
Ok(Expression::Cast {
|
||||
span,
|
||||
kind,
|
||||
value: Box::new(rhs),
|
||||
})
|
||||
})
|
||||
|
||||
#[before(bang_prefix), current(TokenKind::Decrement | TokenKind::Increment | TokenKind::Minus | TokenKind::Plus)]
|
||||
numeric_prefix(|state: &mut State| {
|
||||
let span = state.current.span;
|
||||
let op = state.current.kind.clone();
|
||||
|
||||
state.next();
|
||||
|
||||
let rhs = for_precedence(state, Precedence::Prefix)?;
|
||||
|
||||
let expr = match op {
|
||||
TokenKind::Minus => Expression::Negate {
|
||||
span,
|
||||
value: Box::new(rhs),
|
||||
},
|
||||
TokenKind::Plus => Expression::UnaryPlus {
|
||||
span,
|
||||
value: Box::new(rhs),
|
||||
},
|
||||
TokenKind::Decrement => Expression::PreDecrement {
|
||||
span,
|
||||
value: Box::new(rhs),
|
||||
},
|
||||
TokenKind::Increment => Expression::PreIncrement {
|
||||
span,
|
||||
value: Box::new(rhs),
|
||||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
Ok(expr)
|
||||
})
|
||||
|
||||
#[before(at_prefix), current(TokenKind::Bang)]
|
||||
bang_prefix(|state: &mut State| {
|
||||
let span = state.current.span;
|
||||
|
||||
state.next();
|
||||
|
||||
let rhs = for_precedence(state, Precedence::Bang)?;
|
||||
|
||||
Ok(Expression::BooleanNot {
|
||||
span,
|
||||
value: Box::new(rhs)
|
||||
})
|
||||
})
|
||||
|
||||
#[before(print_prefix), current(TokenKind::At)]
|
||||
at_prefix(|state: &mut State| {
|
||||
let span = state.current.span;
|
||||
|
||||
state.next();
|
||||
|
||||
let rhs = for_precedence(state, Precedence::Prefix)?;
|
||||
|
||||
Ok(Expression::ErrorSuppress {
|
||||
span,
|
||||
expr: Box::new(rhs)
|
||||
})
|
||||
})
|
||||
|
||||
#[before(bitwise_prefix), current(TokenKind::Print)]
|
||||
print_prefix(|state: &mut State| {
|
||||
let span = state.current.span;
|
||||
|
||||
state.next();
|
||||
|
||||
let rhs = for_precedence(state, Precedence::Prefix)?;
|
||||
|
||||
Ok(Expression::Print {
|
||||
span,
|
||||
value: Box::new(rhs)
|
||||
})
|
||||
})
|
||||
|
||||
#[before(dynamic_variable), current(TokenKind::BitwiseNot)]
|
||||
bitwise_prefix(|state: &mut State| {
|
||||
let span = state.current.span;
|
||||
|
||||
state.next();
|
||||
|
||||
let rhs = for_precedence(state, Precedence::Prefix)?;
|
||||
|
||||
Ok(Expression::BitwiseNot {
|
||||
span,
|
||||
value: Box::new(rhs)
|
||||
})
|
||||
})
|
||||
|
||||
#[before(unexpected_token), current(TokenKind::Dollar)]
|
||||
dynamic_variable(|state: &mut State| {
|
||||
variables::dynamic_variable(state)
|
||||
})
|
||||
}
|
||||
|
||||
fn fallback(state: &mut State) -> ParseResult<Expression> {
|
||||
let expr = match &state.current.kind {
|
||||
TokenKind::New => {
|
||||
utils::skip(state, TokenKind::New)?;
|
||||
|
||||
let target = match state.current.kind {
|
||||
TokenKind::Self_ => {
|
||||
if !state.has_class_scope {
|
||||
return Err(ParseError::CannotFindTypeInCurrentScope(
|
||||
state.current.kind.to_string(),
|
||||
state.current.span,
|
||||
));
|
||||
}
|
||||
|
||||
state.next();
|
||||
|
||||
Expression::Self_
|
||||
}
|
||||
TokenKind::Static => {
|
||||
if !state.has_class_scope {
|
||||
return Err(ParseError::CannotFindTypeInCurrentScope(
|
||||
state.current.kind.to_string(),
|
||||
state.current.span,
|
||||
));
|
||||
}
|
||||
|
||||
state.next();
|
||||
|
||||
Expression::Static
|
||||
}
|
||||
TokenKind::Parent => {
|
||||
if !state.has_class_scope {
|
||||
return Err(ParseError::CannotFindTypeInCurrentScope(
|
||||
state.current.kind.to_string(),
|
||||
state.current.span,
|
||||
));
|
||||
}
|
||||
|
||||
state.next();
|
||||
|
||||
Expression::Parent
|
||||
}
|
||||
_ => clone_or_new_precedence(state)?,
|
||||
};
|
||||
|
||||
let mut args = vec![];
|
||||
if state.current.kind == TokenKind::LeftParen {
|
||||
args = parameters::args_list(state)?;
|
||||
}
|
||||
|
||||
Expression::New {
|
||||
target: Box::new(target),
|
||||
args,
|
||||
}
|
||||
}
|
||||
TokenKind::DirConstant => {
|
||||
state.next();
|
||||
Expression::MagicConst {
|
||||
constant: MagicConst::Dir,
|
||||
}
|
||||
}
|
||||
TokenKind::Include
|
||||
| TokenKind::IncludeOnce
|
||||
| TokenKind::Require
|
||||
| TokenKind::RequireOnce => {
|
||||
let kind: IncludeKind = (&state.current.kind).into();
|
||||
state.next();
|
||||
|
||||
let path = lowest_precedence(state)?;
|
||||
|
||||
Expression::Include {
|
||||
kind,
|
||||
path: Box::new(path),
|
||||
}
|
||||
}
|
||||
_ if is_prefix(&state.current.kind) => {
|
||||
let op = state.current.kind.clone();
|
||||
|
||||
state.next();
|
||||
|
||||
let rpred = Precedence::prefix(&op);
|
||||
let rhs = for_precedence(state, rpred)?;
|
||||
|
||||
prefix(&op, rhs)
|
||||
}
|
||||
TokenKind::Dollar => variables::dynamic_variable(state)?,
|
||||
_ => {
|
||||
return Err(ParseError::UnexpectedToken(
|
||||
state.current.kind.to_string(),
|
||||
state.current.span,
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
Ok(expr)
|
||||
fn unexpected_token(state: &mut State) -> ParseResult<Expression> {
|
||||
Err(ParseError::UnexpectedToken(
|
||||
state.current.kind.to_string(),
|
||||
state.current.span,
|
||||
))
|
||||
}
|
||||
|
||||
fn postfix(state: &mut State, lhs: Expression, op: &TokenKind) -> Result<Expression, ParseError> {
|
||||
@ -949,9 +1128,11 @@ fn interpolated_string_part(state: &mut State) -> ParseResult<Option<StringPart>
|
||||
e
|
||||
}
|
||||
TokenKind::Minus => {
|
||||
let span = state.current.span;
|
||||
state.next();
|
||||
if let TokenKind::LiteralInteger(i) = &state.current.kind {
|
||||
let e = Expression::Negate {
|
||||
span,
|
||||
value: Box::new(Expression::LiteralInteger { i: i.clone() }),
|
||||
};
|
||||
state.next();
|
||||
@ -1014,79 +1195,6 @@ fn interpolated_string_part(state: &mut State) -> ParseResult<Option<StringPart>
|
||||
})
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn is_prefix(op: &TokenKind) -> bool {
|
||||
matches!(
|
||||
op,
|
||||
TokenKind::Bang
|
||||
| TokenKind::Print
|
||||
| TokenKind::BitwiseNot
|
||||
| TokenKind::Decrement
|
||||
| TokenKind::Increment
|
||||
| TokenKind::Minus
|
||||
| TokenKind::Plus
|
||||
| TokenKind::StringCast
|
||||
| TokenKind::BinaryCast
|
||||
| TokenKind::ObjectCast
|
||||
| TokenKind::BoolCast
|
||||
| TokenKind::BooleanCast
|
||||
| TokenKind::IntCast
|
||||
| TokenKind::IntegerCast
|
||||
| TokenKind::FloatCast
|
||||
| TokenKind::DoubleCast
|
||||
| TokenKind::RealCast
|
||||
| TokenKind::UnsetCast
|
||||
| TokenKind::ArrayCast
|
||||
| TokenKind::At
|
||||
)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn prefix(op: &TokenKind, rhs: Expression) -> Expression {
|
||||
match op {
|
||||
TokenKind::Print => Expression::Print {
|
||||
value: Box::new(rhs),
|
||||
},
|
||||
TokenKind::Bang => Expression::BooleanNot {
|
||||
value: Box::new(rhs),
|
||||
},
|
||||
TokenKind::Minus => Expression::Negate {
|
||||
value: Box::new(rhs),
|
||||
},
|
||||
TokenKind::Plus => Expression::UnaryPlus {
|
||||
value: Box::new(rhs),
|
||||
},
|
||||
TokenKind::BitwiseNot => Expression::BitwiseNot {
|
||||
value: Box::new(rhs),
|
||||
},
|
||||
TokenKind::Decrement => Expression::PreDecrement {
|
||||
value: Box::new(rhs),
|
||||
},
|
||||
TokenKind::Increment => Expression::PreIncrement {
|
||||
value: Box::new(rhs),
|
||||
},
|
||||
TokenKind::StringCast
|
||||
| TokenKind::BinaryCast
|
||||
| TokenKind::ObjectCast
|
||||
| TokenKind::BoolCast
|
||||
| TokenKind::BooleanCast
|
||||
| TokenKind::IntCast
|
||||
| TokenKind::IntegerCast
|
||||
| TokenKind::FloatCast
|
||||
| TokenKind::DoubleCast
|
||||
| TokenKind::RealCast
|
||||
| TokenKind::UnsetCast
|
||||
| TokenKind::ArrayCast => Expression::Cast {
|
||||
kind: op.into(),
|
||||
value: Box::new(rhs),
|
||||
},
|
||||
TokenKind::At => Expression::ErrorSuppress {
|
||||
expr: Box::new(rhs),
|
||||
},
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_infix(t: &TokenKind) -> bool {
|
||||
matches!(
|
||||
t,
|
||||
|
@ -1,11 +1,11 @@
|
||||
use crate::lexer::token::TokenKind;
|
||||
use crate::parser;
|
||||
use crate::parser::ast::Statement;
|
||||
use crate::parser::error::ParseResult;
|
||||
use crate::parser::expressions;
|
||||
use crate::parser::internal::blocks;
|
||||
use crate::parser::internal::utils;
|
||||
use crate::parser::state::State;
|
||||
use crate::parser;
|
||||
|
||||
pub fn foreach_loop(state: &mut State) -> ParseResult<Statement> {
|
||||
utils::skip(state, TokenKind::Foreach)?;
|
||||
@ -175,21 +175,19 @@ pub fn while_loop(state: &mut State) -> ParseResult<Statement> {
|
||||
let body = if state.current.kind == TokenKind::SemiColon {
|
||||
utils::skip_semicolon(state)?;
|
||||
vec![]
|
||||
} else if state.current.kind == TokenKind::Colon {
|
||||
utils::skip_colon(state)?;
|
||||
let then = blocks::body(state, &TokenKind::EndWhile)?;
|
||||
utils::skip(state, TokenKind::EndWhile)?;
|
||||
utils::skip_semicolon(state)?;
|
||||
then
|
||||
} else if state.current.kind == TokenKind::LeftBrace {
|
||||
utils::skip_left_brace(state)?;
|
||||
let then = blocks::body(state, &TokenKind::RightBrace)?;
|
||||
utils::skip_right_brace(state)?;
|
||||
then
|
||||
} else {
|
||||
if state.current.kind == TokenKind::Colon {
|
||||
utils::skip_colon(state)?;
|
||||
let then = blocks::body(state, &TokenKind::EndWhile)?;
|
||||
utils::skip(state, TokenKind::EndWhile)?;
|
||||
utils::skip_semicolon(state)?;
|
||||
then
|
||||
} else if state.current.kind == TokenKind::LeftBrace {
|
||||
utils::skip_left_brace(state)?;
|
||||
let then = blocks::body(state, &TokenKind::RightBrace)?;
|
||||
utils::skip_right_brace(state)?;
|
||||
then
|
||||
} else {
|
||||
vec![parser::statement(state)?]
|
||||
}
|
||||
vec![parser::statement(state)?]
|
||||
};
|
||||
|
||||
Ok(Statement::While { condition, body })
|
||||
|
@ -41,16 +41,6 @@ pub enum Precedence {
|
||||
}
|
||||
|
||||
impl Precedence {
|
||||
pub fn prefix(kind: &TokenKind) -> Self {
|
||||
use TokenKind::*;
|
||||
|
||||
match kind {
|
||||
Bang => Self::Bang,
|
||||
Clone | New => Self::CloneOrNew,
|
||||
_ => Self::Prefix,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn infix(kind: &TokenKind) -> Self {
|
||||
use TokenKind::*;
|
||||
|
||||
|
@ -22,7 +22,7 @@ pub fn skip_semicolon(state: &mut State) -> ParseResult<Span> {
|
||||
return Err(ParseError::ExpectedToken(
|
||||
vec!["`;`".to_string()],
|
||||
found,
|
||||
state.current.span,
|
||||
end,
|
||||
));
|
||||
} else {
|
||||
state.next();
|
||||
|
16
tests/fixtures/0006/ast.txt
vendored
16
tests/fixtures/0006/ast.txt
vendored
@ -1,6 +1,10 @@
|
||||
[
|
||||
Expression {
|
||||
expr: Include {
|
||||
span: (
|
||||
3,
|
||||
1,
|
||||
),
|
||||
kind: Include,
|
||||
path: LiteralString {
|
||||
value: "foo.php",
|
||||
@ -9,6 +13,10 @@
|
||||
},
|
||||
Expression {
|
||||
expr: Include {
|
||||
span: (
|
||||
5,
|
||||
1,
|
||||
),
|
||||
kind: IncludeOnce,
|
||||
path: LiteralString {
|
||||
value: "bar.php",
|
||||
@ -17,6 +25,10 @@
|
||||
},
|
||||
Expression {
|
||||
expr: Include {
|
||||
span: (
|
||||
7,
|
||||
1,
|
||||
),
|
||||
kind: Require,
|
||||
path: LiteralString {
|
||||
value: "baz.php",
|
||||
@ -25,6 +37,10 @@
|
||||
},
|
||||
Expression {
|
||||
expr: Include {
|
||||
span: (
|
||||
9,
|
||||
1,
|
||||
),
|
||||
kind: RequireOnce,
|
||||
path: LiteralString {
|
||||
value: "qux.php",
|
||||
|
4
tests/fixtures/0010/ast.txt
vendored
4
tests/fixtures/0010/ast.txt
vendored
@ -532,6 +532,10 @@
|
||||
Arg {
|
||||
name: None,
|
||||
value: BitwiseNot {
|
||||
span: (
|
||||
16,
|
||||
13,
|
||||
),
|
||||
value: LiteralInteger {
|
||||
i: "2",
|
||||
},
|
||||
|
4
tests/fixtures/0011/ast.txt
vendored
4
tests/fixtures/0011/ast.txt
vendored
@ -792,6 +792,10 @@
|
||||
Arg {
|
||||
name: None,
|
||||
value: BitwiseNot {
|
||||
span: (
|
||||
16,
|
||||
13,
|
||||
),
|
||||
value: Variable(
|
||||
Variable {
|
||||
start: (
|
||||
|
16
tests/fixtures/0017/ast.txt
vendored
16
tests/fixtures/0017/ast.txt
vendored
@ -50,6 +50,10 @@
|
||||
),
|
||||
op: Assign,
|
||||
rhs: UnaryPlus {
|
||||
span: (
|
||||
4,
|
||||
6,
|
||||
),
|
||||
value: LiteralInteger {
|
||||
i: "1",
|
||||
},
|
||||
@ -73,6 +77,10 @@
|
||||
),
|
||||
op: Assign,
|
||||
rhs: BitwiseNot {
|
||||
span: (
|
||||
5,
|
||||
6,
|
||||
),
|
||||
value: LiteralInteger {
|
||||
i: "2",
|
||||
},
|
||||
@ -96,6 +104,10 @@
|
||||
),
|
||||
op: Assign,
|
||||
rhs: PreDecrement {
|
||||
span: (
|
||||
6,
|
||||
6,
|
||||
),
|
||||
value: Variable(
|
||||
Variable {
|
||||
start: (
|
||||
@ -129,6 +141,10 @@
|
||||
),
|
||||
op: Assign,
|
||||
rhs: PreIncrement {
|
||||
span: (
|
||||
7,
|
||||
6,
|
||||
),
|
||||
value: Variable(
|
||||
Variable {
|
||||
start: (
|
||||
|
4
tests/fixtures/0072/ast.txt
vendored
4
tests/fixtures/0072/ast.txt
vendored
@ -1,6 +1,10 @@
|
||||
[
|
||||
Expression {
|
||||
expr: ErrorSuppress {
|
||||
span: (
|
||||
1,
|
||||
7,
|
||||
),
|
||||
expr: Call {
|
||||
target: Identifier(
|
||||
Identifier {
|
||||
|
4
tests/fixtures/0103/ast.txt
vendored
4
tests/fixtures/0103/ast.txt
vendored
@ -1,6 +1,10 @@
|
||||
[
|
||||
Expression {
|
||||
expr: Print {
|
||||
span: (
|
||||
1,
|
||||
7,
|
||||
),
|
||||
value: Variable(
|
||||
Variable {
|
||||
start: (
|
||||
|
10
tests/fixtures/0237/ast.txt
vendored
10
tests/fixtures/0237/ast.txt
vendored
@ -1,10 +1,18 @@
|
||||
[
|
||||
Expression {
|
||||
expr: Include {
|
||||
span: (
|
||||
3,
|
||||
1,
|
||||
),
|
||||
kind: Require,
|
||||
path: Infix {
|
||||
lhs: MagicConst {
|
||||
constant: Dir,
|
||||
span: (
|
||||
3,
|
||||
9,
|
||||
),
|
||||
constant: Directory,
|
||||
},
|
||||
op: Concat,
|
||||
rhs: LiteralString {
|
||||
|
10
tests/fixtures/0238/ast.txt
vendored
10
tests/fixtures/0238/ast.txt
vendored
@ -16,10 +16,18 @@
|
||||
),
|
||||
op: Assign,
|
||||
rhs: Include {
|
||||
span: (
|
||||
3,
|
||||
8,
|
||||
),
|
||||
kind: Require,
|
||||
path: Infix {
|
||||
lhs: MagicConst {
|
||||
constant: Dir,
|
||||
span: (
|
||||
3,
|
||||
16,
|
||||
),
|
||||
constant: Directory,
|
||||
},
|
||||
op: Concat,
|
||||
rhs: LiteralString {
|
||||
|
4
tests/fixtures/0269/ast.txt
vendored
4
tests/fixtures/0269/ast.txt
vendored
@ -219,6 +219,10 @@
|
||||
[
|
||||
Expression {
|
||||
expr: Print {
|
||||
span: (
|
||||
11,
|
||||
5,
|
||||
),
|
||||
value: Infix {
|
||||
lhs: Variable(
|
||||
Variable {
|
||||
|
74
tests/fixtures/0276 copy/ast.txt
vendored
Normal file
74
tests/fixtures/0276 copy/ast.txt
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
[
|
||||
Expression {
|
||||
expr: MagicConst {
|
||||
span: (
|
||||
3,
|
||||
1,
|
||||
),
|
||||
constant: Directory,
|
||||
},
|
||||
},
|
||||
Expression {
|
||||
expr: MagicConst {
|
||||
span: (
|
||||
4,
|
||||
1,
|
||||
),
|
||||
constant: File,
|
||||
},
|
||||
},
|
||||
Expression {
|
||||
expr: MagicConst {
|
||||
span: (
|
||||
5,
|
||||
1,
|
||||
),
|
||||
constant: Line,
|
||||
},
|
||||
},
|
||||
Expression {
|
||||
expr: MagicConst {
|
||||
span: (
|
||||
6,
|
||||
1,
|
||||
),
|
||||
constant: Namespace,
|
||||
},
|
||||
},
|
||||
Expression {
|
||||
expr: MagicConst {
|
||||
span: (
|
||||
7,
|
||||
1,
|
||||
),
|
||||
constant: Class,
|
||||
},
|
||||
},
|
||||
Expression {
|
||||
expr: MagicConst {
|
||||
span: (
|
||||
8,
|
||||
1,
|
||||
),
|
||||
constant: Method,
|
||||
},
|
||||
},
|
||||
Expression {
|
||||
expr: MagicConst {
|
||||
span: (
|
||||
9,
|
||||
1,
|
||||
),
|
||||
constant: Trait,
|
||||
},
|
||||
},
|
||||
Expression {
|
||||
expr: MagicConst {
|
||||
span: (
|
||||
10,
|
||||
1,
|
||||
),
|
||||
constant: Function,
|
||||
},
|
||||
},
|
||||
]
|
10
tests/fixtures/0276 copy/code.php
vendored
Normal file
10
tests/fixtures/0276 copy/code.php
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
__DIR__;
|
||||
__FILE__;
|
||||
__LINE__;
|
||||
__NAMESPACE__;
|
||||
__CLASS__;
|
||||
__METHOD__;
|
||||
__TRAIT__;
|
||||
__FUNCTION__;
|
2
tests/fixtures/0276/code.php
vendored
2
tests/fixtures/0276/code.php
vendored
@ -12,4 +12,4 @@ while ($a) $A;
|
||||
|
||||
do $A; while ($a);
|
||||
|
||||
declare (a='b') $C;
|
||||
declare (a='b') $C;
|
||||
|
Loading…
Reference in New Issue
Block a user