/*!
* Copyright (C) 2017 Glayzzle (BSD3 License)
* @authors https://github.com/glayzzle/php-parser/graphs/contributors
* @url http://glayzzle.com
*/
"use strict";
module.exports = {
/**
* Reads a namespace declaration block
* ```ebnf
* namespace ::= T_NAMESPACE namespace_name? '{'
* top_statements
* '}'
* | T_NAMESPACE namespace_name ';' top_statements
* ```
* @see http://php.net/manual/en/language.namespaces.php
* @return {Namespace}
*/
read_namespace: function() {
var result = this.node('namespace');
this.expect(this.tok.T_NAMESPACE) && this.next();
if (this.token == '{') {
this.currentNamespace = [''];
var body = this.nextWithComments().read_top_statements();
this.expect('}') && this.nextWithComments();
return result([''], body, true);
} else {
var name = this.read_namespace_name();
if (this.token == ';') {
this.currentNamespace = name;
var body = this.nextWithComments().read_top_statements();
this.expect(this.EOF);
return result(name.name, body, false);
} else if (this.token == '{') {
this.currentNamespace = name;
var body = this.nextWithComments().read_top_statements();
this.expect('}') && this.nextWithComments();
return result(name.name, body, true);
} else if (this.token === '(') {
// resolve ambuiguity between namespace & function call
name.resolution = this.ast.identifier.RELATIVE_NAME;
name.name = name.name.substring(1);
return this.node('call')(
name, this.read_function_argument_list()
);
} else {
this.error(['{', ';']);
// graceful mode :
this.currentNamespace = name;
var body = this.read_top_statements();
this.expect(this.EOF);
return result(name, body, false);
}
}
}
/**
* Reads a namespace name
* ```ebnf
* namespace_name ::= T_NS_SEPARATOR? (T_STRING T_NS_SEPARATOR)* T_STRING
* ```
* @see http://php.net/manual/en/language.namespaces.rules.php
* @return {Identifier}
*/
,read_namespace_name: function() {
var result = this.node('identifier'), relative = false;
if (this.token === this.tok.T_NAMESPACE) {
this.next().expect(this.tok.T_NS_SEPARATOR) && this.next();
relative = true
}
return result(
this.read_list(this.tok.T_STRING, this.tok.T_NS_SEPARATOR, true),
relative
);
}
/**
* Reads a use statement
* ```ebnf
* use_statement ::= T_USE
* use_type? use_declarations |
* use_type use_statement '{' use_declarations '}' |
* use_statement '{' use_declarations(=>typed) '}'
* ';'
* ```
* @see http://php.net/manual/en/language.namespaces.importing.php
* @return {UseGroup}
*/
,read_use_statement: function() {
var result = this.node('usegroup'),
type = null,
items = [],
name = null
;
this.expect(this.tok.T_USE) && this.next();
type = this.read_use_type();
items.push(this.read_use_declaration(false));
if (this.token === ',') {
items = items.concat(this.next().read_use_declarations(false));
} else if (this.token === '{') {
name = items[0].name;
items = this.next().read_use_declarations(type === null);
this.expect('}') && this.next();
}
this.expect(';') && this.nextWithComments();
return result(name, type, items);
}
/**
* Reads a use declaration
* ```ebnf
* use_declaration ::= use_type? namespace_name use_alias
* ```
* @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L380
* @return {UseItem}
*/
,read_use_declaration: function(typed) {
var result = this.node('useitem'), type = null;
if (typed) type = this.read_use_type();
var name = this.read_namespace_name();
var alias = this.read_use_alias();
return result(name.name, alias, type);
}
/**
* Reads a list of use declarations
* ```ebnf
* use_declarations ::= use_declaration (',' use_declaration)*
* ```
* @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L380
* @return {UseItem[]}
*/
,read_use_declarations: function(typed) {
var result = [this.read_use_declaration(typed)];
while(this.token === ',') {
result.push(this.next().read_use_declaration(typed));
}
return result;
}
/**
* Reads a use statement
* ```ebnf
* use_alias ::= (T_AS T_STRING)?
* ```
* @return {String|null}
*/
,read_use_alias: function() {
var result = null;
if (this.token === this.tok.T_AS) {
Eif (this.next().expect(this.tok.T_STRING)) {
result = this.text();
this.next();
}
}
return result;
}
/**
* Reads the namespace type declaration
* ```ebnf
* use_type ::= (T_FUNCTION | T_CONST)?
* ```
* @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L335
* @return {String|null} Possible values : function, const
*/
,read_use_type: function() {
if (this.token === this.tok.T_FUNCTION) {
this.next();
return this.ast.useitem.TYPE_FUNCTION;
} else if (this.token === this.tok.T_CONST) {
this.next();
return this.ast.useitem.TYPE_CONST;
}
return null;
}
};
|