mirror of
https://github.com/danog/parser.git
synced 2024-11-27 04:14:55 +01:00
Merge pull request #31 from edsrzf/parse-include
This commit is contained in:
commit
0f0629ff8b
@ -846,6 +846,8 @@ fn identifier_to_keyword(ident: &str) -> Option<TokenKind> {
|
|||||||
"foreach" => TokenKind::Foreach,
|
"foreach" => TokenKind::Foreach,
|
||||||
"function" => TokenKind::Function,
|
"function" => TokenKind::Function,
|
||||||
"if" => TokenKind::If,
|
"if" => TokenKind::If,
|
||||||
|
"include" => TokenKind::Include,
|
||||||
|
"include_once" => TokenKind::IncludeOnce,
|
||||||
"implements" => TokenKind::Implements,
|
"implements" => TokenKind::Implements,
|
||||||
"interface" => TokenKind::Interface,
|
"interface" => TokenKind::Interface,
|
||||||
"instanceof" => TokenKind::Instanceof,
|
"instanceof" => TokenKind::Instanceof,
|
||||||
|
@ -90,6 +90,8 @@ pub enum TokenKind {
|
|||||||
Identifier(String),
|
Identifier(String),
|
||||||
If,
|
If,
|
||||||
Implements,
|
Implements,
|
||||||
|
Include,
|
||||||
|
IncludeOnce,
|
||||||
Increment,
|
Increment,
|
||||||
InlineHtml(String),
|
InlineHtml(String),
|
||||||
Instanceof,
|
Instanceof,
|
||||||
|
@ -143,6 +143,26 @@ pub struct StaticVar {
|
|||||||
pub default: Option<Expression>,
|
pub default: Option<Expression>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Serialize)]
|
||||||
|
pub enum IncludeKind {
|
||||||
|
Include,
|
||||||
|
IncludeOnce,
|
||||||
|
Require,
|
||||||
|
RequireOnce,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&TokenKind> for IncludeKind {
|
||||||
|
fn from(k: &TokenKind) -> Self {
|
||||||
|
match k {
|
||||||
|
TokenKind::Include => IncludeKind::Include,
|
||||||
|
TokenKind::IncludeOnce => IncludeKind::IncludeOnce,
|
||||||
|
TokenKind::Require => IncludeKind::Require,
|
||||||
|
TokenKind::RequireOnce => IncludeKind::RequireOnce,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Serialize)]
|
#[derive(Debug, PartialEq, Clone, Serialize)]
|
||||||
pub enum Statement {
|
pub enum Statement {
|
||||||
InlineHtml(String),
|
InlineHtml(String),
|
||||||
@ -166,10 +186,8 @@ pub enum Statement {
|
|||||||
value_var: Expression,
|
value_var: Expression,
|
||||||
body: Block,
|
body: Block,
|
||||||
},
|
},
|
||||||
Require {
|
Include {
|
||||||
path: Expression,
|
kind: IncludeKind,
|
||||||
},
|
|
||||||
RequireOnce {
|
|
||||||
path: Expression,
|
path: Expression,
|
||||||
},
|
},
|
||||||
Var {
|
Var {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
Arg, ArrayItem, BackedEnumType, ClassFlag, ClosureUse, ElseIf, MagicConst, MethodFlag,
|
Arg, ArrayItem, BackedEnumType, ClassFlag, ClosureUse, ElseIf, IncludeKind, MagicConst,
|
||||||
StaticVar, Use, UseKind,
|
MethodFlag, StaticVar, Use, UseKind,
|
||||||
},
|
},
|
||||||
Block, Case, Catch, Expression, Identifier, MatchArm, Program, Statement, Type,
|
Block, Case, Catch, Expression, Identifier, MatchArm, Program, Statement, Type,
|
||||||
};
|
};
|
||||||
@ -208,23 +208,18 @@ impl Parser {
|
|||||||
|
|
||||||
Statement::While { condition, body }
|
Statement::While { condition, body }
|
||||||
}
|
}
|
||||||
TokenKind::Require => {
|
TokenKind::Include
|
||||||
|
| TokenKind::IncludeOnce
|
||||||
|
| TokenKind::Require
|
||||||
|
| TokenKind::RequireOnce => {
|
||||||
|
let kind: IncludeKind = (&self.current.kind).into();
|
||||||
self.next();
|
self.next();
|
||||||
|
|
||||||
let path = self.expression(0)?;
|
let path = self.expression(0)?;
|
||||||
|
|
||||||
self.semi()?;
|
self.semi()?;
|
||||||
|
|
||||||
Statement::Require { path }
|
Statement::Include { kind, path }
|
||||||
}
|
|
||||||
TokenKind::RequireOnce => {
|
|
||||||
self.next();
|
|
||||||
|
|
||||||
let path = self.expression(0)?;
|
|
||||||
|
|
||||||
self.semi()?;
|
|
||||||
|
|
||||||
Statement::RequireOnce { path }
|
|
||||||
}
|
}
|
||||||
TokenKind::For => {
|
TokenKind::For => {
|
||||||
self.next();
|
self.next();
|
||||||
@ -2089,7 +2084,7 @@ impl Display for ParseError {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::Parser;
|
use super::Parser;
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{Arg, ArrayItem, ElseIf, InfixOp, MethodFlag, PropertyFlag},
|
ast::{Arg, ArrayItem, ElseIf, IncludeKind, InfixOp, MethodFlag, PropertyFlag},
|
||||||
Expression, Identifier, Param, Statement, Type,
|
Expression, Identifier, Param, Statement, Type,
|
||||||
};
|
};
|
||||||
use trunk_lexer::Lexer;
|
use trunk_lexer::Lexer;
|
||||||
@ -2161,6 +2156,49 @@ mod tests {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn include() {
|
||||||
|
assert_ast(
|
||||||
|
"<?php include 'foo.php';",
|
||||||
|
&[Statement::Include {
|
||||||
|
path: Expression::ConstantString {
|
||||||
|
value: "foo.php".into(),
|
||||||
|
},
|
||||||
|
kind: IncludeKind::Include,
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_ast(
|
||||||
|
"<?php include_once 'foo.php';",
|
||||||
|
&[Statement::Include {
|
||||||
|
path: Expression::ConstantString {
|
||||||
|
value: "foo.php".into(),
|
||||||
|
},
|
||||||
|
kind: IncludeKind::IncludeOnce,
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_ast(
|
||||||
|
"<?php require 'foo.php';",
|
||||||
|
&[Statement::Include {
|
||||||
|
path: Expression::ConstantString {
|
||||||
|
value: "foo.php".into(),
|
||||||
|
},
|
||||||
|
kind: IncludeKind::Require,
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_ast(
|
||||||
|
"<?php require_once 'foo.php';",
|
||||||
|
&[Statement::Include {
|
||||||
|
path: Expression::ConstantString {
|
||||||
|
value: "foo.php".into(),
|
||||||
|
},
|
||||||
|
kind: IncludeKind::RequireOnce,
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn instanceof() {
|
fn instanceof() {
|
||||||
assert_ast(
|
assert_ast(
|
||||||
@ -2986,15 +3024,25 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn comment_at_end_of_class() {
|
fn comment_at_end_of_class() {
|
||||||
assert_ast("<?php
|
assert_ast(
|
||||||
|
"<?php
|
||||||
class MyClass {
|
class MyClass {
|
||||||
protected $a;
|
protected $a;
|
||||||
// my comment
|
// my comment
|
||||||
}", &[
|
}",
|
||||||
Statement::Class { name: "MyClass".into(), extends: None, implements: vec![], body: vec![
|
&[Statement::Class {
|
||||||
Statement::Property { var: "a".into(), value: None, r#type: None, flags: vec![PropertyFlag::Protected] }
|
name: "MyClass".into(),
|
||||||
], flag: None }
|
extends: None,
|
||||||
]);
|
implements: vec![],
|
||||||
|
body: vec![Statement::Property {
|
||||||
|
var: "a".into(),
|
||||||
|
value: None,
|
||||||
|
r#type: None,
|
||||||
|
flags: vec![PropertyFlag::Protected],
|
||||||
|
}],
|
||||||
|
flag: None,
|
||||||
|
}],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_ast(source: &str, expected: &[Statement]) {
|
fn assert_ast(source: &str, expected: &[Statement]) {
|
||||||
|
Loading…
Reference in New Issue
Block a user