mirror of
https://github.com/danog/parser.git
synced 2024-11-26 20:04:57 +01:00
fix: namespace parser
Signed-off-by: azjezz <azjezz@protonmail.com>
This commit is contained in:
parent
1f4875c802
commit
974c04db85
@ -30,6 +30,8 @@ pub enum ParseError {
|
||||
UnpredictableState(Span),
|
||||
StaticPropertyUsingReadonlyModifier(String, String, Span),
|
||||
ReadonlyPropertyHasDefaultValue(String, String, Span),
|
||||
MixingBracedAndUnBracedNamespaceDeclarations(Span),
|
||||
NestedNamespaceDeclarations(Span),
|
||||
}
|
||||
|
||||
impl Display for ParseError {
|
||||
@ -72,6 +74,8 @@ impl Display for ParseError {
|
||||
Self::UnpredictableState(span) => write!(f, "Parse Error: Reached an unpredictable state on line {} column {}", span.0, span.1),
|
||||
Self::StaticPropertyUsingReadonlyModifier(class, prop, span) => write!(f, "Parse Error: Static property {}:${} cannot be readonly on line {} column {}", class, prop, span.0, span.1),
|
||||
Self::ReadonlyPropertyHasDefaultValue(class, prop, span) => write!(f, "Parse Error: Readonly property {}:${} cannot have a default value on line {} column {}", class, prop, span.0, span.1),
|
||||
Self::MixingBracedAndUnBracedNamespaceDeclarations(span) => write!(f, "Parse Error: Cannot mix braced namespace declarations with unbraced namespace declarations on line {} column {}", span.0, span.1),
|
||||
Self::NestedNamespaceDeclarations(span) => write!(f, "Parse Error: Namespace declarations cannot be mixed on line {} column {}", span.0, span.1),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,10 +16,21 @@ impl Parser {
|
||||
|
||||
/// Expect an unqualified or qualified identifier such as Foo, Bar or Foo\Bar.
|
||||
pub(in crate::parser) fn name(&self, state: &mut State) -> ParseResult<ByteString> {
|
||||
Ok(expect_token!([
|
||||
TokenKind::Identifier(identifier) => identifier,
|
||||
TokenKind::QualifiedIdentifier(qualified) => qualified,
|
||||
], state, "an identifier"))
|
||||
expect_token!([
|
||||
TokenKind::Identifier(name) | TokenKind::QualifiedIdentifier(name) => Ok(name),
|
||||
], state, "an identifier")
|
||||
}
|
||||
|
||||
/// Expect an optional unqualified or qualified identifier such as Foo, Bar or Foo\Bar.
|
||||
pub(in crate::parser) fn optional_name(&self, state: &mut State) -> Option<ByteString> {
|
||||
match state.current.kind.clone() {
|
||||
TokenKind::Identifier(name) | TokenKind::QualifiedIdentifier(name) => {
|
||||
state.next();
|
||||
|
||||
Some(name)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Expect an unqualified, qualified or fully qualified identifier such as Foo, Foo\Bar or \Foo\Bar.
|
||||
|
@ -4,6 +4,7 @@ pub mod classish_statement;
|
||||
pub mod flags;
|
||||
pub mod functions;
|
||||
pub mod ident;
|
||||
pub mod namespace;
|
||||
pub mod params;
|
||||
pub mod precedence;
|
||||
pub mod punc;
|
||||
|
86
src/parser/internal/namespace.rs
Normal file
86
src/parser/internal/namespace.rs
Normal file
@ -0,0 +1,86 @@
|
||||
use crate::lexer::token::TokenKind;
|
||||
use crate::parser::ast::Block;
|
||||
use crate::parser::ast::Statement;
|
||||
use crate::parser::error::ParseError;
|
||||
use crate::parser::error::ParseResult;
|
||||
use crate::parser::state::NamespaceType;
|
||||
use crate::parser::state::Scope;
|
||||
use crate::parser::state::State;
|
||||
use crate::parser::Parser;
|
||||
use crate::prelude::ByteString;
|
||||
use crate::scoped;
|
||||
|
||||
impl Parser {
|
||||
pub(in crate::parser) fn namespace(&self, state: &mut State) -> ParseResult<Statement> {
|
||||
state.next();
|
||||
|
||||
let name = self.optional_name(state);
|
||||
|
||||
if let Some(name) = &name {
|
||||
if state.current.kind != TokenKind::LeftBrace {
|
||||
match state.namespace_type() {
|
||||
Some(NamespaceType::Braced) => {
|
||||
return Err(ParseError::MixingBracedAndUnBracedNamespaceDeclarations(
|
||||
state.current.span,
|
||||
));
|
||||
}
|
||||
Some(NamespaceType::Unbraced) => {
|
||||
// exit the current namespace scope.
|
||||
// we don't need to check if the current scope is a namespace
|
||||
// because we know it is, it is not possible for it to be anything else.
|
||||
// as using `namespace` anywhere aside from a top-level stmt would result
|
||||
// in a parse error.
|
||||
state.exit();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
return self.unbraced_namespace(state, name.clone());
|
||||
}
|
||||
}
|
||||
|
||||
match state.namespace_type() {
|
||||
Some(NamespaceType::Unbraced) => Err(
|
||||
ParseError::MixingBracedAndUnBracedNamespaceDeclarations(state.current.span),
|
||||
),
|
||||
Some(NamespaceType::Braced) if state.namespace().is_some() => {
|
||||
Err(ParseError::NestedNamespaceDeclarations(state.current.span))
|
||||
}
|
||||
_ => self.braced_namespace(state, name),
|
||||
}
|
||||
}
|
||||
|
||||
fn unbraced_namespace(&self, state: &mut State, name: ByteString) -> ParseResult<Statement> {
|
||||
let body = scoped!(state, Scope::Namespace(name.clone()), {
|
||||
let mut body = Block::new();
|
||||
while !state.is_eof() {
|
||||
body.push(self.top_level_statement(state)?);
|
||||
}
|
||||
|
||||
Ok(body)
|
||||
})?;
|
||||
|
||||
Ok(Statement::Namespace { name, body })
|
||||
}
|
||||
|
||||
fn braced_namespace(
|
||||
&self,
|
||||
state: &mut State,
|
||||
name: Option<ByteString>,
|
||||
) -> ParseResult<Statement> {
|
||||
self.lbrace(state)?;
|
||||
|
||||
let body = scoped!(state, Scope::BracedNamespace(name.clone()), {
|
||||
let mut body = Block::new();
|
||||
while state.current.kind != TokenKind::RightBrace && !state.is_eof() {
|
||||
body.push(self.top_level_statement(state)?);
|
||||
}
|
||||
|
||||
Ok(body)
|
||||
})?;
|
||||
|
||||
self.rbrace(state)?;
|
||||
|
||||
Ok(Statement::BracedNamespace { name, body })
|
||||
}
|
||||
}
|
@ -11,9 +11,7 @@ use crate::parser::error::ParseError;
|
||||
use crate::parser::error::ParseResult;
|
||||
use crate::parser::internal::ident::is_reserved_ident;
|
||||
use crate::parser::internal::precedence::{Associativity, Precedence};
|
||||
use crate::parser::state::Scope;
|
||||
use crate::parser::state::State;
|
||||
use crate::scoped;
|
||||
|
||||
pub mod ast;
|
||||
pub mod error;
|
||||
@ -62,49 +60,7 @@ impl Parser {
|
||||
state.skip_comments();
|
||||
|
||||
let statement = match &state.current.kind {
|
||||
TokenKind::Namespace => {
|
||||
state.next();
|
||||
|
||||
if state.current.kind != TokenKind::LeftBrace {
|
||||
let name = self.name(state)?;
|
||||
|
||||
if state.current.kind == TokenKind::LeftBrace {
|
||||
self.lbrace(state)?;
|
||||
|
||||
let body = scoped!(state, Scope::BracedNamespace(Some(name.clone())), {
|
||||
self.block(state, &TokenKind::RightBrace)
|
||||
})?;
|
||||
|
||||
self.rbrace(state)?;
|
||||
|
||||
Statement::BracedNamespace {
|
||||
name: Some(name),
|
||||
body,
|
||||
}
|
||||
} else {
|
||||
let body = scoped!(state, Scope::Namespace(name.clone()), {
|
||||
let mut body = Block::new();
|
||||
while !state.is_eof() {
|
||||
body.push(self.top_level_statement(state)?);
|
||||
}
|
||||
|
||||
Ok(body)
|
||||
})?;
|
||||
|
||||
Statement::Namespace { name, body }
|
||||
}
|
||||
} else {
|
||||
self.lbrace(state)?;
|
||||
|
||||
let body = scoped!(state, Scope::BracedNamespace(None), {
|
||||
self.block(state, &TokenKind::RightBrace)
|
||||
})?;
|
||||
|
||||
self.rbrace(state)?;
|
||||
|
||||
Statement::BracedNamespace { name: None, body }
|
||||
}
|
||||
}
|
||||
TokenKind::Namespace => self.namespace(state)?,
|
||||
TokenKind::Use => {
|
||||
state.next();
|
||||
|
||||
@ -521,11 +477,7 @@ impl Parser {
|
||||
};
|
||||
|
||||
let mut cases = Vec::new();
|
||||
loop {
|
||||
if state.current.kind == end_token {
|
||||
break;
|
||||
}
|
||||
|
||||
while state.current.kind != end_token {
|
||||
match state.current.kind {
|
||||
TokenKind::Case => {
|
||||
state.next();
|
||||
|
@ -9,6 +9,12 @@ use crate::parser::ast::MethodFlag;
|
||||
use crate::parser::error::ParseError;
|
||||
use crate::parser::error::ParseResult;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub enum NamespaceType {
|
||||
Braced,
|
||||
Unbraced,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub enum Scope {
|
||||
Namespace(ByteString),
|
||||
@ -33,6 +39,7 @@ pub struct State {
|
||||
pub peek: Token,
|
||||
pub iter: IntoIter<Token>,
|
||||
pub comments: Vec<Token>,
|
||||
pub namespace_type: Option<NamespaceType>,
|
||||
}
|
||||
|
||||
impl State {
|
||||
@ -45,30 +52,40 @@ impl State {
|
||||
peek: iter.next().unwrap_or_default(),
|
||||
iter,
|
||||
comments: vec![],
|
||||
namespace_type: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn named(&self, name: &ByteString) -> String {
|
||||
let mut namespace = None;
|
||||
/// Return the namespace type used in the current state
|
||||
///
|
||||
/// The namespace type is retrieve from the last entered
|
||||
/// namespace scope.
|
||||
///
|
||||
/// Note: even when a namespace scope is exited, the namespace type
|
||||
/// is retained, until the next namespace scope is entered.
|
||||
pub fn namespace_type(&self) -> Option<NamespaceType> {
|
||||
self.namespace_type.clone()
|
||||
}
|
||||
|
||||
pub fn namespace(&self) -> Option<&Scope> {
|
||||
for scope in &self.stack {
|
||||
match scope {
|
||||
Scope::Namespace(n) => {
|
||||
namespace = Some(n.to_string());
|
||||
|
||||
break;
|
||||
}
|
||||
Scope::BracedNamespace(n) => {
|
||||
namespace = n.as_ref().map(|s| s.to_string());
|
||||
|
||||
break;
|
||||
Scope::Namespace(_) | Scope::BracedNamespace(_) => {
|
||||
return Some(scope);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
match namespace {
|
||||
Some(v) => format!("{}\\{}", v, name),
|
||||
None => name.to_string(),
|
||||
None
|
||||
}
|
||||
|
||||
pub fn named(&self, name: &ByteString) -> String {
|
||||
match self.namespace() {
|
||||
Some(Scope::Namespace(n)) | Some(Scope::BracedNamespace(Some(n))) => {
|
||||
format!("{}\\{}", n, name)
|
||||
}
|
||||
_ => name.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,8 +101,18 @@ impl State {
|
||||
.ok_or(ParseError::UnpredictableState(self.current.span))
|
||||
}
|
||||
|
||||
pub fn enter(&mut self, state: Scope) {
|
||||
self.stack.push_back(state);
|
||||
pub fn enter(&mut self, scope: Scope) {
|
||||
match &scope {
|
||||
Scope::Namespace(_) => {
|
||||
self.namespace_type = Some(NamespaceType::Unbraced);
|
||||
}
|
||||
Scope::BracedNamespace(_) => {
|
||||
self.namespace_type = Some(NamespaceType::Braced);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
self.stack.push_back(scope);
|
||||
}
|
||||
|
||||
pub fn exit(&mut self) {
|
||||
|
18
tests/0157/ast.txt
Normal file
18
tests/0157/ast.txt
Normal file
@ -0,0 +1,18 @@
|
||||
[
|
||||
BracedNamespace {
|
||||
name: Some(
|
||||
"Foo\Bar",
|
||||
),
|
||||
body: [
|
||||
Function {
|
||||
name: Identifier {
|
||||
name: "foo",
|
||||
},
|
||||
params: [],
|
||||
body: [],
|
||||
return_type: None,
|
||||
by_ref: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
5
tests/0157/code.php
Normal file
5
tests/0157/code.php
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace Foo\Bar {
|
||||
function foo() {}
|
||||
}
|
85
tests/0157/tokens.txt
Normal file
85
tests/0157/tokens.txt
Normal file
@ -0,0 +1,85 @@
|
||||
[
|
||||
Token {
|
||||
kind: OpenTag(
|
||||
Full,
|
||||
),
|
||||
span: (
|
||||
1,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Namespace,
|
||||
span: (
|
||||
3,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: QualifiedIdentifier(
|
||||
"Foo\Bar",
|
||||
),
|
||||
span: (
|
||||
3,
|
||||
11,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBrace,
|
||||
span: (
|
||||
3,
|
||||
19,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Function,
|
||||
span: (
|
||||
4,
|
||||
6,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Identifier(
|
||||
"foo",
|
||||
),
|
||||
span: (
|
||||
4,
|
||||
15,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftParen,
|
||||
span: (
|
||||
4,
|
||||
18,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightParen,
|
||||
span: (
|
||||
4,
|
||||
19,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBrace,
|
||||
span: (
|
||||
4,
|
||||
21,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBrace,
|
||||
span: (
|
||||
4,
|
||||
22,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBrace,
|
||||
span: (
|
||||
5,
|
||||
1,
|
||||
),
|
||||
},
|
||||
]
|
32
tests/0158/ast.txt
Normal file
32
tests/0158/ast.txt
Normal file
@ -0,0 +1,32 @@
|
||||
[
|
||||
Namespace {
|
||||
name: "Foo\Bar",
|
||||
body: [
|
||||
Noop,
|
||||
Function {
|
||||
name: Identifier {
|
||||
name: "foo",
|
||||
},
|
||||
params: [],
|
||||
body: [],
|
||||
return_type: None,
|
||||
by_ref: false,
|
||||
},
|
||||
Namespace {
|
||||
name: "Foo\Baz",
|
||||
body: [
|
||||
Noop,
|
||||
Function {
|
||||
name: Identifier {
|
||||
name: "foo",
|
||||
},
|
||||
params: [],
|
||||
body: [],
|
||||
return_type: None,
|
||||
by_ref: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
9
tests/0158/code.php
Normal file
9
tests/0158/code.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Foo\Bar;
|
||||
|
||||
function foo() {}
|
||||
|
||||
namespace Foo\Baz;
|
||||
|
||||
function foo() {}
|
145
tests/0158/tokens.txt
Normal file
145
tests/0158/tokens.txt
Normal file
@ -0,0 +1,145 @@
|
||||
[
|
||||
Token {
|
||||
kind: OpenTag(
|
||||
Full,
|
||||
),
|
||||
span: (
|
||||
1,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Namespace,
|
||||
span: (
|
||||
3,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: QualifiedIdentifier(
|
||||
"Foo\Bar",
|
||||
),
|
||||
span: (
|
||||
3,
|
||||
11,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: SemiColon,
|
||||
span: (
|
||||
3,
|
||||
18,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Function,
|
||||
span: (
|
||||
5,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Identifier(
|
||||
"foo",
|
||||
),
|
||||
span: (
|
||||
5,
|
||||
10,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftParen,
|
||||
span: (
|
||||
5,
|
||||
13,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightParen,
|
||||
span: (
|
||||
5,
|
||||
14,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBrace,
|
||||
span: (
|
||||
5,
|
||||
16,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBrace,
|
||||
span: (
|
||||
5,
|
||||
17,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Namespace,
|
||||
span: (
|
||||
7,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: QualifiedIdentifier(
|
||||
"Foo\Baz",
|
||||
),
|
||||
span: (
|
||||
7,
|
||||
11,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: SemiColon,
|
||||
span: (
|
||||
7,
|
||||
18,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Function,
|
||||
span: (
|
||||
9,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Identifier(
|
||||
"foo",
|
||||
),
|
||||
span: (
|
||||
9,
|
||||
10,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftParen,
|
||||
span: (
|
||||
9,
|
||||
13,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightParen,
|
||||
span: (
|
||||
9,
|
||||
14,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBrace,
|
||||
span: (
|
||||
9,
|
||||
16,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBrace,
|
||||
span: (
|
||||
9,
|
||||
17,
|
||||
),
|
||||
},
|
||||
]
|
9
tests/0159/code.php
Normal file
9
tests/0159/code.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Foo\Bar;
|
||||
|
||||
function foo() {}
|
||||
|
||||
namespace Foo\Baz {
|
||||
function foo() {}
|
||||
}
|
1
tests/0159/parser-error.txt
Normal file
1
tests/0159/parser-error.txt
Normal file
@ -0,0 +1 @@
|
||||
MixingBracedAndUnBracedNamespaceDeclarations((7, 19)) -> Parse Error: Cannot mix braced namespace declarations with unbraced namespace declarations on line 7 column 19
|
152
tests/0159/tokens.txt
Normal file
152
tests/0159/tokens.txt
Normal file
@ -0,0 +1,152 @@
|
||||
[
|
||||
Token {
|
||||
kind: OpenTag(
|
||||
Full,
|
||||
),
|
||||
span: (
|
||||
1,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Namespace,
|
||||
span: (
|
||||
3,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: QualifiedIdentifier(
|
||||
"Foo\Bar",
|
||||
),
|
||||
span: (
|
||||
3,
|
||||
11,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: SemiColon,
|
||||
span: (
|
||||
3,
|
||||
18,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Function,
|
||||
span: (
|
||||
5,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Identifier(
|
||||
"foo",
|
||||
),
|
||||
span: (
|
||||
5,
|
||||
10,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftParen,
|
||||
span: (
|
||||
5,
|
||||
13,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightParen,
|
||||
span: (
|
||||
5,
|
||||
14,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBrace,
|
||||
span: (
|
||||
5,
|
||||
16,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBrace,
|
||||
span: (
|
||||
5,
|
||||
17,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Namespace,
|
||||
span: (
|
||||
7,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: QualifiedIdentifier(
|
||||
"Foo\Baz",
|
||||
),
|
||||
span: (
|
||||
7,
|
||||
11,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBrace,
|
||||
span: (
|
||||
7,
|
||||
19,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Function,
|
||||
span: (
|
||||
8,
|
||||
5,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Identifier(
|
||||
"foo",
|
||||
),
|
||||
span: (
|
||||
8,
|
||||
14,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftParen,
|
||||
span: (
|
||||
8,
|
||||
17,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightParen,
|
||||
span: (
|
||||
8,
|
||||
18,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBrace,
|
||||
span: (
|
||||
8,
|
||||
20,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBrace,
|
||||
span: (
|
||||
8,
|
||||
21,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBrace,
|
||||
span: (
|
||||
9,
|
||||
1,
|
||||
),
|
||||
},
|
||||
]
|
9
tests/0160/code.php
Normal file
9
tests/0160/code.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Foo\Baz {
|
||||
function foo() {}
|
||||
|
||||
namespace Foo\Bar;
|
||||
|
||||
function foo() {}
|
||||
}
|
1
tests/0160/parser-error.txt
Normal file
1
tests/0160/parser-error.txt
Normal file
@ -0,0 +1 @@
|
||||
MixingBracedAndUnBracedNamespaceDeclarations((6, 22)) -> Parse Error: Cannot mix braced namespace declarations with unbraced namespace declarations on line 6 column 22
|
152
tests/0160/tokens.txt
Normal file
152
tests/0160/tokens.txt
Normal file
@ -0,0 +1,152 @@
|
||||
[
|
||||
Token {
|
||||
kind: OpenTag(
|
||||
Full,
|
||||
),
|
||||
span: (
|
||||
1,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Namespace,
|
||||
span: (
|
||||
3,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: QualifiedIdentifier(
|
||||
"Foo\Baz",
|
||||
),
|
||||
span: (
|
||||
3,
|
||||
11,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBrace,
|
||||
span: (
|
||||
3,
|
||||
19,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Function,
|
||||
span: (
|
||||
4,
|
||||
5,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Identifier(
|
||||
"foo",
|
||||
),
|
||||
span: (
|
||||
4,
|
||||
14,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftParen,
|
||||
span: (
|
||||
4,
|
||||
17,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightParen,
|
||||
span: (
|
||||
4,
|
||||
18,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBrace,
|
||||
span: (
|
||||
4,
|
||||
20,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBrace,
|
||||
span: (
|
||||
4,
|
||||
21,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Namespace,
|
||||
span: (
|
||||
6,
|
||||
5,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: QualifiedIdentifier(
|
||||
"Foo\Bar",
|
||||
),
|
||||
span: (
|
||||
6,
|
||||
15,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: SemiColon,
|
||||
span: (
|
||||
6,
|
||||
22,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Function,
|
||||
span: (
|
||||
8,
|
||||
5,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Identifier(
|
||||
"foo",
|
||||
),
|
||||
span: (
|
||||
8,
|
||||
14,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftParen,
|
||||
span: (
|
||||
8,
|
||||
17,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightParen,
|
||||
span: (
|
||||
8,
|
||||
18,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBrace,
|
||||
span: (
|
||||
8,
|
||||
20,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBrace,
|
||||
span: (
|
||||
8,
|
||||
21,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBrace,
|
||||
span: (
|
||||
9,
|
||||
1,
|
||||
),
|
||||
},
|
||||
]
|
9
tests/0161/code.php
Normal file
9
tests/0161/code.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Foo\Baz {
|
||||
function foo() {}
|
||||
}
|
||||
|
||||
namespace Foo\Bar;
|
||||
|
||||
function foo() {}
|
1
tests/0161/parser-error.txt
Normal file
1
tests/0161/parser-error.txt
Normal file
@ -0,0 +1 @@
|
||||
MixingBracedAndUnBracedNamespaceDeclarations((7, 18)) -> Parse Error: Cannot mix braced namespace declarations with unbraced namespace declarations on line 7 column 18
|
152
tests/0161/tokens.txt
Normal file
152
tests/0161/tokens.txt
Normal file
@ -0,0 +1,152 @@
|
||||
[
|
||||
Token {
|
||||
kind: OpenTag(
|
||||
Full,
|
||||
),
|
||||
span: (
|
||||
1,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Namespace,
|
||||
span: (
|
||||
3,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: QualifiedIdentifier(
|
||||
"Foo\Baz",
|
||||
),
|
||||
span: (
|
||||
3,
|
||||
11,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBrace,
|
||||
span: (
|
||||
3,
|
||||
19,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Function,
|
||||
span: (
|
||||
4,
|
||||
5,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Identifier(
|
||||
"foo",
|
||||
),
|
||||
span: (
|
||||
4,
|
||||
14,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftParen,
|
||||
span: (
|
||||
4,
|
||||
17,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightParen,
|
||||
span: (
|
||||
4,
|
||||
18,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBrace,
|
||||
span: (
|
||||
4,
|
||||
20,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBrace,
|
||||
span: (
|
||||
4,
|
||||
21,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBrace,
|
||||
span: (
|
||||
5,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Namespace,
|
||||
span: (
|
||||
7,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: QualifiedIdentifier(
|
||||
"Foo\Bar",
|
||||
),
|
||||
span: (
|
||||
7,
|
||||
11,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: SemiColon,
|
||||
span: (
|
||||
7,
|
||||
18,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Function,
|
||||
span: (
|
||||
9,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Identifier(
|
||||
"foo",
|
||||
),
|
||||
span: (
|
||||
9,
|
||||
10,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftParen,
|
||||
span: (
|
||||
9,
|
||||
13,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightParen,
|
||||
span: (
|
||||
9,
|
||||
14,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBrace,
|
||||
span: (
|
||||
9,
|
||||
16,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBrace,
|
||||
span: (
|
||||
9,
|
||||
17,
|
||||
),
|
||||
},
|
||||
]
|
9
tests/0162/code.php
Normal file
9
tests/0162/code.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace {
|
||||
function foo() {}
|
||||
}
|
||||
|
||||
namespace Foo\Bar;
|
||||
|
||||
function foo() {}
|
1
tests/0162/parser-error.txt
Normal file
1
tests/0162/parser-error.txt
Normal file
@ -0,0 +1 @@
|
||||
MixingBracedAndUnBracedNamespaceDeclarations((7, 18)) -> Parse Error: Cannot mix braced namespace declarations with unbraced namespace declarations on line 7 column 18
|
143
tests/0162/tokens.txt
Normal file
143
tests/0162/tokens.txt
Normal file
@ -0,0 +1,143 @@
|
||||
[
|
||||
Token {
|
||||
kind: OpenTag(
|
||||
Full,
|
||||
),
|
||||
span: (
|
||||
1,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Namespace,
|
||||
span: (
|
||||
3,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBrace,
|
||||
span: (
|
||||
3,
|
||||
11,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Function,
|
||||
span: (
|
||||
4,
|
||||
5,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Identifier(
|
||||
"foo",
|
||||
),
|
||||
span: (
|
||||
4,
|
||||
14,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftParen,
|
||||
span: (
|
||||
4,
|
||||
17,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightParen,
|
||||
span: (
|
||||
4,
|
||||
18,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBrace,
|
||||
span: (
|
||||
4,
|
||||
20,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBrace,
|
||||
span: (
|
||||
4,
|
||||
21,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBrace,
|
||||
span: (
|
||||
5,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Namespace,
|
||||
span: (
|
||||
7,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: QualifiedIdentifier(
|
||||
"Foo\Bar",
|
||||
),
|
||||
span: (
|
||||
7,
|
||||
11,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: SemiColon,
|
||||
span: (
|
||||
7,
|
||||
18,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Function,
|
||||
span: (
|
||||
9,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Identifier(
|
||||
"foo",
|
||||
),
|
||||
span: (
|
||||
9,
|
||||
10,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftParen,
|
||||
span: (
|
||||
9,
|
||||
13,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightParen,
|
||||
span: (
|
||||
9,
|
||||
14,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBrace,
|
||||
span: (
|
||||
9,
|
||||
16,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBrace,
|
||||
span: (
|
||||
9,
|
||||
17,
|
||||
),
|
||||
},
|
||||
]
|
5
tests/0163/code.php
Normal file
5
tests/0163/code.php
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace;
|
||||
|
||||
function foo() {}
|
1
tests/0163/parser-error.txt
Normal file
1
tests/0163/parser-error.txt
Normal file
@ -0,0 +1 @@
|
||||
ExpectedToken(["`{`"], Some(";"), (3, 10)) -> Parse Error: unexpected token `;`, expecting `{` on line 3 column 10
|
69
tests/0163/tokens.txt
Normal file
69
tests/0163/tokens.txt
Normal file
@ -0,0 +1,69 @@
|
||||
[
|
||||
Token {
|
||||
kind: OpenTag(
|
||||
Full,
|
||||
),
|
||||
span: (
|
||||
1,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Namespace,
|
||||
span: (
|
||||
3,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: SemiColon,
|
||||
span: (
|
||||
3,
|
||||
10,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Function,
|
||||
span: (
|
||||
5,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Identifier(
|
||||
"foo",
|
||||
),
|
||||
span: (
|
||||
5,
|
||||
10,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftParen,
|
||||
span: (
|
||||
5,
|
||||
13,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightParen,
|
||||
span: (
|
||||
5,
|
||||
14,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBrace,
|
||||
span: (
|
||||
5,
|
||||
16,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBrace,
|
||||
span: (
|
||||
5,
|
||||
17,
|
||||
),
|
||||
},
|
||||
]
|
32
tests/0164/ast.txt
Normal file
32
tests/0164/ast.txt
Normal file
@ -0,0 +1,32 @@
|
||||
[
|
||||
BracedNamespace {
|
||||
name: None,
|
||||
body: [
|
||||
Function {
|
||||
name: Identifier {
|
||||
name: "foo",
|
||||
},
|
||||
params: [],
|
||||
body: [],
|
||||
return_type: None,
|
||||
by_ref: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
BracedNamespace {
|
||||
name: Some(
|
||||
"a",
|
||||
),
|
||||
body: [
|
||||
Function {
|
||||
name: Identifier {
|
||||
name: "foo",
|
||||
},
|
||||
params: [],
|
||||
body: [],
|
||||
return_type: None,
|
||||
by_ref: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
9
tests/0164/code.php
Normal file
9
tests/0164/code.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace {
|
||||
function foo() {}
|
||||
}
|
||||
|
||||
namespace a {
|
||||
function foo() {}
|
||||
}
|
150
tests/0164/tokens.txt
Normal file
150
tests/0164/tokens.txt
Normal file
@ -0,0 +1,150 @@
|
||||
[
|
||||
Token {
|
||||
kind: OpenTag(
|
||||
Full,
|
||||
),
|
||||
span: (
|
||||
1,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Namespace,
|
||||
span: (
|
||||
3,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBrace,
|
||||
span: (
|
||||
3,
|
||||
11,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Function,
|
||||
span: (
|
||||
4,
|
||||
5,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Identifier(
|
||||
"foo",
|
||||
),
|
||||
span: (
|
||||
4,
|
||||
14,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftParen,
|
||||
span: (
|
||||
4,
|
||||
17,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightParen,
|
||||
span: (
|
||||
4,
|
||||
18,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBrace,
|
||||
span: (
|
||||
4,
|
||||
20,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBrace,
|
||||
span: (
|
||||
4,
|
||||
21,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBrace,
|
||||
span: (
|
||||
5,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Namespace,
|
||||
span: (
|
||||
7,
|
||||
1,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Identifier(
|
||||
"a",
|
||||
),
|
||||
span: (
|
||||
7,
|
||||
11,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBrace,
|
||||
span: (
|
||||
7,
|
||||
13,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Function,
|
||||
span: (
|
||||
8,
|
||||
5,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: Identifier(
|
||||
"foo",
|
||||
),
|
||||
span: (
|
||||
8,
|
||||
14,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftParen,
|
||||
span: (
|
||||
8,
|
||||
17,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightParen,
|
||||
span: (
|
||||
8,
|
||||
18,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: LeftBrace,
|
||||
span: (
|
||||
8,
|
||||
20,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBrace,
|
||||
span: (
|
||||
8,
|
||||
21,
|
||||
),
|
||||
},
|
||||
Token {
|
||||
kind: RightBrace,
|
||||
span: (
|
||||
9,
|
||||
1,
|
||||
),
|
||||
},
|
||||
]
|
Loading…
Reference in New Issue
Block a user